• 第5章学习总结


    一、这一章学习了树和二叉树,下面是我的思维导图:

    二、实践,小组合作代码及注释

     

    实践2:

    
    

       1 #include<iostream> 

       2 using namespace std;

       3

       4

     5 typedef char ElementType;
     6 typedef struct TreeNode Tree;
     7 //结构体
     8 struct TreeNode {
     9     ElementType data;
    10     int left;
    11     int right;
    12 }t1[101],t2[101];//t1是第一棵树,t2是第二棵树
    13
    14 int Build(Tree t[]) 
    15 {//建立二叉树
    16     bool a[101] = { false };
    17     int n;
    18     cin >> n;
    19     char data, left, right;
    20     for (int i = 0; i < n; i++)
    21     {
    22         cin >> data >> left >> right;
    23         t[i].data = data;
    24         //判断左右节点是否空
    25         if (left == '-')
    26             t[i].left = -1;
    27         else {
    28             t[i].left = left-'0';
    29             a[(int)left - 48] = true;
    30         }
    31         
    32         if (right == '-')
    33             t[i].right = -1;
    34         else {
    35             t[i].right = (int)right-48;
    36             a[(int)right - 48] = true;
    37         }
    38     }
    39     //判断是不是根节点,根节点没有双亲结点
    40     for (int i = 0; i < n; i++)
    41     {
    42         //cout << t[i].data <<" "<< t[i].left <<" "<< t[i].right <<" "<< a[i] << endl;;
    43         if (!a[i])
    44             return i;
    45     }
    46     return -1;
    47 }
    48 
    49 bool Compare(int r1,int r2)
    50 {
    51     if (r1 == -1 && r2 == -1)
    52         return true;//都是空,同构
    53     else if ((r1 == -1 && r2 != -1) || (r2 == -1 && r1 != -1))
    54         return false;//其中一个为空,不同构
    55     else if (t1[r1].data != t2[r2].data)
    56         return false;//根数据不同,不同构
    57     else if (t1[r1].left == -1 && t2[r2].left == -1)
    58         return Compare(t1[r1].right, t2[r2].right);//左子树为空,则判断右子树
    59     else if ((t1[r1].left != -1 && t2[r2].left != -1) && (t1[t1[r1].left].data == t2[t2[r2].left].data))
    60         return Compare(t1[r1].left, t2[r2].left) && Compare(t1[r1].right, t2[r2].right);///两树左子树皆不空,且值相等 ,判断其子树
    61 else 62 return Compare(t1[r1].left, t2[r2].right) && Compare(t1[r1].right, t2[r2].left);//两树左子树有一个空 或者 皆不空但值不等,交换左右子树判断 63 } 64 65 int main() 66 { 67 int root1 = Build(t1); 68 int root2 = Build(t2); 69 70 bool flag = Compare(root1, root2); 71 if (flag) 72 cout << "Yes" << endl; 73 else 74 cout << "No" << endl; 75 return 0; 76 }

    小组合作:

     1 /*思路:
     2 1.定义结点的结构体,其中把每个结点的孩子作为一个孩子数组;再定义结构体数组作为树,其中结构体数组的下标就是结点的编号
     3 2.创建树并记录根结点的编号(即结构体数组T的下标)
     4 3.根据层次遍历的方法,最后一个访问的结点就是最深的叶子结点
     5 4.释放动态申请的空间*/
     6 #include<iostream>
     7 #include<queue>
     8 //#define Max 100000
     9 using namespace std;
    10 typedef struct
    11 {//定义结点
    12     int m;//结点的孩子数 
    13     int* child;//用数组存放结点的孩子们 要释放空间 
    14 }TNode;//利用数组下标对应结点编号,(所以就不在结构体里定义编号,省空间?) 
    15 
    16 int create(TNode *T,int n);
    17 void levelOrder(TNode *T,int R);
    18 void destroy(TNode *T,int n); 
    19 
    20 int main()
    21 {
    22     int n;
    23     cin >> n;
    24     TNode* T;
    25     T = new TNode[n + 1];//数组下标就是结点的编号
    26     int R;//根结点的编号
    27     R=create(T, n);
    28     levelOrder(T,R);
    29     destroy(T,n);//int* child
    30     delete[]T;//TNode* T
    31     return 0;
    32 }
    33 int create(TNode* T, int n)
    34 {
    35     bool* check;//为了查找根结点 
    36     check = new bool[n + 1];//动态申请check数组的空间 
    37     //check[n + 1] = { false };
    38     for(int i=0;i<n+1;i++)
    39     {
    40         check[i]=false;//初始化为false,最后不为true的元素的下标就是根结点的编号 
    41     }
    42     int root=-1;//需要先初始化
    43     //开始输入
    44     for (int i = 1; i < n + 1; i++)
    45     {
    46         cin >> T[i].m;
    47         if (T[i].m != 0)//如果结点i有孩子
    48         {
    49             int ch;
    50             T[i].child = new int[T[i].m];//为结点i申请m个孩子的空间
    51             for (int j = 0; j < T[i].m; j++)
    52             {
    53                 cin >> ch;
    54                 T[i].child[j] = ch;
    55                 check[ch] = true;
    56             }
    57         }
    58     
    59     }
    60     for (int i = 1; i < n + 1; i++)
    61         {
    62             if (check[i] == false)//此时i就是根结点的编号 
    63             {
    64                 root = i;
    65                 break;
    66             }
    67         }
    68     delete []check ;//因为 check = new bool[n + 1]
    69     return root;
    70 }
    71 void levelOrder(TNode* T,int R)
    72 {
    73     queue<int> Q;
    74     Q.push(R);//根结点先入队,R就代表根结点,而不是T[R]或者T[R]的成员,因为在结构体里面没有表示结点编号的成员 
    75     int e;//记录出队的队头元素 
    76     while(!Q.empty())
    77     {
    78         e=Q.front();//先把队头元素的值赋给e 
    79         Q.pop();//再让队头出队 
    80         if(T[e].m!=0)//如果刚出队的队头e有孩子,就让它的孩子们入队 
    81         {
    82             for(int k=0;k<T[e].m;k++)
    83             Q.push(T[e].child[k]);
    84         }
    85      } 
    86      cout<<e<<endl;//最后一个出队的就是最深叶子 
    87 }
    88 void destroy(TNode *T,int n)
    89 {
    90     for(int k=1;k<n+1;k++)//检查每个结点 1~n 
    91     {
    92         if(T[k].m!=0)//如果当前结点i有孩子,就要释放这个结点中为child动态申请的空间 
    93         {
    94             delete []T[k].child;
    95         }
    96     }
    97     
    98 }

     三、个人总结

    我感觉我这一章并没有怎么学好,自我反思自己因为最近太忙,而放在思考代码、课本概念的时间比较少,从而感觉完成小组合作、个人代码的时候有点困难

    目标:整理前几次课堂笔记,抽时间把课本再看一遍,总结课堂讨论题;下一阶段的学习希望自己能够自律一点,抽出时间,沉住气的打代码

  • 相关阅读:
    注意安全 保重身体
    抽象和接口的区别
    哪些设计模式最值得学习
    超级扫盲什么是设计模式?
    简单工厂、工厂方法和抽象工厂模式
    通过领域模型设计物流系统
    json过滤特殊字符
    数据库性能优化JOIN方法说明[转]
    策略模式
    观察者模式
  • 原文地址:https://www.cnblogs.com/lsy-273700263/p/13022039.html
Copyright © 2020-2023  润新知