• 数据结构学习第十二天


    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("")  但是不行 

    后面又想用 二叉树中后代为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);
    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
    ", &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

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

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

    然后递归输出 后序遍历

  • 相关阅读:
    【模板小程序】链表排序(qsort/insert_sort/merge_sort)
    链表回文判断(C++)
    【模板小程序】十进制大数除法(输出商和余数)
    【模板小程序】字符串截取
    【模板小程序】翻转一个句子中的单词
    web前端基础背景
    MongoDB基本知识(补充)
    Python-ORM
    Python-元编程
    ElementUI 中 el-table 获取当前选中行的index
  • 原文地址:https://www.cnblogs.com/57one/p/11416440.html
Copyright © 2020-2023  润新知