数据结构基础_二叉树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构基础_二叉树相关的知识,希望对你有一定的参考价值。

二叉树

二叉树(Binary Tree)的递归定义:二叉树要么为空,要么由根节点(root)、左子树(left subtree)和右子树(right subtree)组成。

小球落下

题目:一棵二叉树,初始开关关闭。当小球到达一个内节点时,如果该节点上的开关关闭,则往左走,否则往右走,直到走到叶结点。

  输入:

    4 2
    3 4
    10 1
    2 2
    8 128
    16 12345

  输出:

    12
    7
    512
    3
    255
    36358

  思路:只需看小球的编号的奇偶性,就能知道它是最终在哪棵树中。对于那些落入根节点左子树的小球来说,秩序知道该小球是第几个落在根的左子树里,就可以知道他下一步是往左还是往右。

 1 #include <stdio.h>
 2 #include<stdio.h>
 3 const int MAXD=20;
 4 int main() {
 5     int D,I;
 6     while(scanf("%d%d",&D,&I)!=EOF){
 7         int k=1;
 8         for(int i=0;i<D-1;i++){
 9             if(I%2==1){k=k*2;I=(I+1)/2;}
10             else {k=k*2+1;I=I/2;}
11         }
12             printf("%d\n",k);
13     }
14     return 0;
15 }

 层次遍历

题目:输入一棵二叉树,你的任务是按从上到下,从左到右的顺序输出各个节点的值。如果从根节点到某个叶结点的路径上有的节点没有在输入中给出,或者给出了超过了一次,应当输出 -1。

节点个数不超过256.

  输入:

    (11,LL) (7,LLL) (8,R) (5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()
    (3,L) (4,R) ()

  输出:

    5 4 8 11 13 4 7 2 1

思路:采用动态结构,根据需要建立新的节点,然后把它们组织称一棵树。

六步:

  1. 二叉树的定义和操作。首先需要定义一个称为Node的数据类型,并且对应整棵二叉树的树根root。
  2. 每次需要一个Node时,都要用malloc函数申请内存,并返回一个未初始化的空间,把申请的新结点的操作封装到newnode函数中。
  3. 创建addonde函数,它按照序列行走,目标不存在是调用newnode来创建新结点。
  4. 接下来是释放一棵二叉树的代码。
  5. 编写输入部分和主函数。不停读入结点,如果在读到空括号之前文件结束,则返回0。这里两次调用了C语言的灵活性,可以把任意”指向字符的指针“看成是字符串,从该位置开始,直到字符‘0’。例如,读入字符”(11,LL)“,则&s[1]所对应的字符串是"11,LL)"。
  6. 输入和建树部分已经结束,接下来需要按照层次顺序遍历这棵树。我们使用一个队列来完成这个任务,初始时只有一个根节点,然后每次取出一个节点,就把它的左右儿子放进队。
  sscanf(&s[1],"%d",&v);因为这句话多了个双引号,改的要死。最后面还是学长找出来的。
  • 理解不透彻吧,sscanf第一个参数表示字符串(要读出来的),如果是数据就要引用,比如“10kk010”,如果是字符串就不用双引号,就不用双引号,就不用双引号!
  • 第二个参数是格式规范,就是你要输入的下一个数据的类型,或者是你要输入对第一个参数的提取。比如要提取第一个0后面的数据就,"%*[^k]%s"。
  • 第三个数据就是对应要输入的数据地址符号,或者buf缓冲区(要读进去的)。
 1 #include <stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 const int MAXN=256;
 5 char s[MAXN];
 6 int failed;
 7 int n=0,ans[MAXN];//节点总数和输出队列
 8 //二叉树的结点定义和操作。
 9 //节点类型
10 typedef struct Tnode{
11     int have_value;//是否被赋值过
12     int v;//结点值
13     struct Tnode *left,*right;
14 }Node;
15 Node* root;//二叉树根节点
16 //把申请的结点的操作封装到newnode
17 Node* newnode(){
18     Node* u=(Node*) malloc(sizeof(Node));
19     if(u!=NULL){
20         u->have_value=0;
21         u->left=u->right=NULL;
22     }
23     return u;
24 }
25 //addnode函数,它按照移动序列走,目标不存在时调用newnode来创建新的节点。
26 void addnode(int v,char* s){
27     int n=strlen(s);
28     Node* u=root;//从根节点往下走
29     for(int i=0;i<n;i++){
30         if(s[i]==L){
31             if(u->left==NULL) u->left=newnode();//节点不存在,建立新的节点
32             u=u->left;//往左走
33         }
34         else if(s[i]==R){
35             if(u->right==NULL) u->right=newnode();
36             u=u->right;
37         }
38     }
39     if(u->have_value)failed=1;//已经赋过值,表示输入有误
40     u->v=v;
41     u->have_value=1;
42 }
43 
44 void remove_tree(Node *u){
45     if(u==NULL) return;
46     remove_tree(u->left);//递归释放左子树
47     remove_tree(u->right);//递归释放右子树
48     free(u);//释放u节点本身的内存
49 }
50 //输入部分和主程序
51 int read_input(){
52     failed=0;
53     remove_tree(root);
54     root=newnode();
55     for(;;){
56         if(scanf("%s",s)!=1)return 0;//整个输出结束
57         if(!strcmp(s,"()"))break;//读到结束标志,退出循环
58         int v;
59         sscanf(&s[1],"%d",&v);
60         addnode(v,strchr(s,,)+1);
61     }
62     return 1;
63 }
64 //接下来需要按照层次遍历的顺序遍历这棵树
65 int bfs(){
66     int front=0,rear=1;
67     Node* q[MAXN];
68     q[0]=root;
69     while(front<rear){
70         Node* u=q[front++];
71         if(!u->have_value) return 0;//有节点没有被赋值过,表明输入有误。
72         ans[n++]=u->v;
73         if(u->left!=NULL)q[rear++]=u->left;
74         if(u->right!=NULL)q[rear++]=u->right;
75     }
76     return 1;
77 }
78 
79 
80 
81 
82 int main() {
83     while(read_input()){
84         if(bfs()==0||failed==1) printf("-1\n");
85         else{
86             for(int i=0;i<n;i++){
87                 printf("%d ",ans[i]);
88             }
89             printf("\n");
90         }
91     }
92     return 0;
93 }

 

二叉树重建

题目:输入一棵二叉树的先序遍历和中序遍历序列,输出它的后序遍历序列。

  输入:

      DBACEGF ABCDEFG

      BCAD CBAD

  输出:

      ACBFGED
      CDAB

 1 #include <stdio.h>
 2 #include<string.h>
 3 const int MAXN=1010;
 4 char ans[MAXN],s1[MAXN],s2[MAXN];
 5 void build(int n,char *s1,char *s2,char *s){
 6     if(n<=0)return;
 7     int p=strchr(s2,s1[0])-s2;
 8     //s2代表字符的s2的起始地址的位置从0开始,
 9     build(p,s1+1,s2,s);//递归左子树的后序遍历
10     build(n-p-1,s1+p+1,s2+p+1,s+p);//递归右子树的后序遍历
11     s[n-1]=s1[0];//把根节点添加到最后
12 }
13 int main() {
14     while(scanf("%s%s",s1,s2)!=EOF){
15         int n=strlen(s1);
16         build(n,s1,s2,ans);
17         ans[n]=\0;//添加字符结束的标志
18         printf("%s\n",ans);
19     }
20     return 0;
21 }

 

以上是关于数据结构基础_二叉树的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之树(Tree)_二叉树的创建及遍历概述

数据结构二叉树经典基础习题

Python数据结构系列☀️《树与二叉树-基础知识》——知识点讲解+代码实现☀️

数据结构树相关代码(数据结构笔试复测Leecode牛客)

数据结构6.3_遍历二叉树和线索二叉树

基础数据结构二叉树代码实现