数据结构学习第十二天

09:43:33 2019-08-27

努力

 

对于非空二叉树  ${n_0}$是表示叶节点的个数

${n_0}+{n_1}+{n_2}-{1}=0*{n_0}+1*{n_1}+2*{n_2}$

即可得出

${n_0}={n_2}+{1}$

二叉树的遍历方法

 

PTA  第6题 判断2个树是否同构

 1 #define _CRT_SECURE_NO_WARNINGS 
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 struct  TreeNode
 5 {
 6     char Data;
 7     int LChild;
 8     int RChild;
 9 }Tree1[10],Tree2[10];
10 
11 int Change(const char num)    //将读入的字符修改后返回
12 {
13     if (num != '-')
14         return num - '0';
15     else
16         return -1;
17 }
18 int Charge(int T1,int T2)   //判别2个树是否重构
19 {
20     if (T1 == -1 && T2 == -1)   //都为空树 为同构
21         return 1;
22     if ((T1 == -1 && T2 != -1) || (T1 != -1 && T2 == -1)) //一空 一不空 不同构
23         return 0;
24     if (Tree1[T1].Data != Tree2[T2].Data)  //节点的值不一样 不同构
25         return 0;
26     if (Tree1[T1].LChild == -1 && Tree2[T2].LChild == -1)    //无左子树
27         return Charge(Tree1[T1].RChild, Tree2[T2].RChild);
28     if ((Tree1[T1].LChild != -1 && Tree2[T2].LChild != -1) && Tree1[Tree1[T1].LChild].Data == Tree2[Tree2[T2].LChild].Data)
29         return (Charge(Tree1[T1].LChild, Tree2[T2].LChild) && Charge(Tree1[T1].RChild, Tree2[T2].RChild));
30     else
31         return (Charge(Tree1[T1].LChild, Tree2[T2].RChild) && Charge(Tree1[T1].RChild, Tree2[T2].LChild));
32 }
33 int BulidTree(struct TreeNode Tree[])
34 {
35     int N;
36     int Root=0;
37     int Check[10] = { 0 };     //用数组来记录哪个值未出现
38     scanf("%d", &N);
39     if (!N)
40     {
41         Root = -1;
42     }
43     char c, num1, num2;
44     for (int i = 0; i < N; i++)
45     {
46         getchar();
47         scanf("%c %c %c", &c, &num1, &num2);
48         Tree[i].Data = c;
49         Tree[i].LChild = Change(num1);   //对字符进行改变 并返回整数
50         if (Tree[i].LChild != -1) Check[Tree[i].LChild] = 1;
51         Tree[i].RChild = Change(num2);
52         if (Tree[i].RChild != -1) Check[Tree[i].RChild] = 1;
53     }
54     for (int i = 0; i < N; i++)
55         if (!Check[i])
56         {
57             Root = i;
58             break;
59         }
60     return Root;
61 }
62 int main()
63 {
64     int TreeA, TreeB;
65     TreeA = BulidTree(Tree1);
66     TreeB = BulidTree(Tree2);
67     if (Charge(TreeA,TreeB))
68         printf("Yes");
69     else
70         printf("No");
71 }
View Code
PTA 第7题 找出所有树叶
  1 #define _CRT_SECURE_NO_WARNINGS 
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #define Size 10
  5 int Queue[10];
  6 int Front=1;
  7 int Rear=0;
  8 int size = 0;
  9 int Num[10] = { 0 };//用来收集数据
 10 int j = -1;   //用于访问数组
 11 int Succ(int n)
 12 {
 13     if (n < Size)
 14         return n;
 15     else
 16         return 0;
 17 }
 18 void EnQueue(int num)
 19 {
 20     Rear = Succ(Rear + 1);
 21     Queue[Rear] = num;
 22     size++;
 23 }
 24 int DeQueue()
 25 {
 26     size--;
 27     int num = Queue[Front];
 28     Front = Succ(Front+1);
 29     return num;
 30 }
 31 struct  TreeNode
 32 {
 33     int LChild;
 34     int RChild;
 35 }Tree[10];
 36 int Change(char num)
 37 {
 38     if (num == '-')
 39         return -1;
 40     else
 41         return num - '0';
 42 }
 43 int BuildTree(struct TreeNode T[])
 44 {
 45     int Root=-1;
 46     int N=0;
 47     int Check[10] = { 0 }; //记录哪个节点未出现
 48     scanf("%d", &N);
 49     for (int i = 0; i < N; i++)
 50     {
 51         getchar();
 52         char num1, num2;
 53         scanf("%c %c", &num1, &num2);
 54         T[i].LChild = Change(num1);
 55         T[i].RChild = Change(num2);
 56         if (T[i].LChild != -1) Check[T[i].LChild] = 1;
 57         if (T[i].RChild != -1) Check[T[i].RChild] = 1;
 58     }
 59     for (int i = 0; i < N; i++)
 60         if (!Check[i])
 61         {
 62             Root = i;
 63             break;
 64         }
 65     return Root;
 66 }
 67 void FindLeves(int T)            //利用队列实现层序遍历
 68 {
 69     if (T == -1)
 70         return;
 71     //int i = 0;  //用来计算 A2的个数
 72     EnQueue(T);
 73     while (size)
 74     {
 75         int t = DeQueue();
 76         if(Tree[t].LChild!=-1)EnQueue(Tree[t].LChild);
 77         if(Tree[t].RChild!=-1)EnQueue(Tree[t].RChild);
 78         if (Tree[t].RChild != -1 && Tree[t].RChild != -1);
 79         if (Tree[t].LChild == -1 && Tree[t].RChild == -1)
 80                 Num[++j] = t;
 81             /*if(i)
 82                 printf("%d ", t);
 83             else
 84                 printf("%d", t);*/
 85     }
 86 }
 87 
 88 int main()
 89 {
 90     int T;
 91     T = BuildTree(Tree);
 92     FindLeves(T);
 93     for (int i = 0; i <=j; i++)
 94     {
 95         if(i!=j)
 96             printf("%d ", Num[i]);
 97         else
 98             printf("%d", Num[i]); 
 99     }
100     return 0;
101 }
View Code

写第题是格式出了问题 题上要求最后末位不能多个空格  我想在最后加上printf("\b")  但是不行 

后面又想用 二叉树中后代为0与后代为2的关系 即$A_0=A_2+1$ 来做 也不行  上网也没搜到好方法(可能我没认真看)  最后老老实实拿数组做了

PTA 第8题 已知前序遍历和中序遍历 输出 后序遍历  (os:课程上说这道题不难 我做了好几个小时。。。我是憨憨)

 1 #define _CRT_SECURE_NO_WARNINGS 
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 struct  TreeNode
 6 {
 7     int LChild;
 8     int RChild;
 9 }Tree[50];
10 int size; //记录大小 因为最后一个值后不加空格
11 int l;
12 int Stack[30];
13 int i;    //栈的标志 
14 int Pre[30];    //记录前序遍历的结果  1,2,3,4,5,6
15 int j;
16 int Inorder[30];  //记录中序遍历的结果 3,2,4,1,6,5
17 int k;
18 void Scan()
19 {
20     int N = 0;
21     scanf("%d\n", &N);
22     N *= 2;
23     char Str[10] = { 0 };
24     int num;
25     while (N--)
26     {
27         scanf("%s ", Str);
28         if (!strcmp(Str,"Push"))
29         {
30             scanf("%d\n", &Pre[j++]);
31             Stack[i++] = Pre[j - 1];
32         }
33         else
34         {
35             Inorder[k++] = Stack[--i];
36         }
37     }
38     size =k;
39 }
40 int BuildTree(int lo1,int hi1,int lo2,int hi2)
41 {
42     int root = Pre[lo1];     //递归中的第一个值都是 要求的节点
43     for (int m =lo2; m < hi2; m++)
44     {
45         if (root == Inorder[m])
46         {
47             if (lo1 + 1 < lo1 + 1 + m-lo2)Tree[root].LChild = BuildTree(lo1 + 1, lo1 + 1 + m-lo2, lo2, m);    //不断递归 缩减问题规模
48             else Tree[root].LChild=-1;        //当大小缩小至1时 为树叶
49             if (lo1+1+m <lo1+hi2)Tree[root].RChild = BuildTree(lo1 + 1 + m - lo2, lo1+hi2, m + 1, hi2);
50             else Tree[root].RChild=-1; 
51         }
52     }
53     return root;    //返回 节点
54 }
55 void Print(int Root)
56 {
57     if(Root!=-1)
58     {
59         Print(Tree[Root].LChild);
60         Print(Tree[Root].RChild);
61         if (size-->1)
62             printf("%d ", Root);
63         else
64             printf("%d", Root);
65     }
66 }
67 int main()
68 {
69     Scan();
70     int Root=BuildTree(0,j,0,k);
71     Print(Root);
72     return 0;
73 }
View Code

何佬在视频中讲过 已知 三种遍历方式中(前序中序后序)知道其中两个 可以确定二叉树的情况是 :必须存在中序遍历

利用递归 不断缩减问题规模 先用 前序遍历和中序遍历 确定好二叉树并 读入到 数组中(用动态也可以) 

然后递归输出 后序遍历

posted @ 2019-08-28 00:56  57one  阅读(120)  评论(0编辑  收藏  举报