第五章学习小结
一. 完成作业或实践时解决困难的经验分享
这部分讲作业和实践第二题的编程思路。
作业一:创建根,左孩子,右孩子的结构体
1 struct Node 2 { 3 int pos; 4 char left; 5 char right; 6 Node() 7 { 8 pos = -1; 9 left = -1; 10 right = -1; 11 } 12 }; 13 typedef struct Node* node;
创建用来传递的队列的结构体
struct Queue { struct Node data[MAXSIZE]; int front; int rear; }; typedef struct Queue* queue;
主函数
1 int main() 2 { 3 struct Node list[MAXSIZE]; 4 int N; 5 cin >> N; 6 input(list, N); 7 8 int *a = new int[N]; 9 for (int i = 0; i < N; i++) a[i] = 0; //记录叶子结点 10 11 process(a, list,N); 12 13 int root = find(list, N); 14 int sum=0; 15 for (int i = 0; i < N; i++) 16 { 17 if (a[i] == 1) sum++; 18 }//因为需要按照从上到下,从左到右的顺序打印,所以对对树进行层序遍历,按照遍历顺序依次打印叶子结点 19 int *level = levelOrder(list, root); 20 for (int i = 0; i < N && sum>1; i++) 21 { 22 if (a[level[i]] == 1) 23 { 24 cout << level[i] << ' '; 25 sum--; 26 } 27 } 28 for (int i = N - 1; i >= 0; i--) 29 { 30 if (a[level[i]] == 1) 31 { 32 cout << level[i]; 33 break; 34 } 35 } 36 37 delete[] a; 38 return 0; 39 }//输入函数
查找叶子结点
1 void input(struct Node * list, int N) 2 { 3 for (int i = 0; i < N; i++) 4 { 5 list[i].pos = i; 6 cin >> list[i].left >> list[i].right; 7 } 8 }
查找树根
1 void process(int * a, struct Node * node,int N) 2 { 3 for (int i = 0; i < N; i++) 4 { 5 if (node[i].left == '-'&&node[i].right == '-') a[i] = 1; 6 } 7 }
查找末结点并赋值
1 int find(struct Node * T, int N) 2 { 3 int *a = new int[N]; 4 for (int i = 0; i < N; i++) a[i] = 0; 5 for (int i = 0; i < N; i++) 6 { 7 if (T[i].left != '-') 8 { 9 int l = T[i].left - '0'; 10 a[l] = 1; 11 } 12 if (T[i].right != '-') 13 { 14 int r = T[i].right - '0'; 15 a[r] = 1; 16 } 17 } 18 int i; 19 for ( i = 0; i < N; i++) if (!a[i]) break; 20 delete[] a; 21 return i; 22 }
队列操作
1 int integer(char a) 2 { 3 return a - '0'; 4 }//创建一个空的队列 5 6 7 queue CreateQueue() 8 { 9 queue Q = new struct Queue; 10 Q->front = -1; 11 Q->rear = -1; 12 13 return Q; 14 }//出队 15 16 17 struct Node deleteQueue(queue Q) 18 { 19 if (isEmpty(Q)) 20 { 21 cout << "Queue is empty!" << endl; 22 } 23 else 24 { 25 Q->front = Q->front + 1;//Q->data[Q->front] ; 26 return Q->data[Q->front]; 27 } 28 }//入队 29 30 31 void addQueue(queue q, struct Node data) 32 { 33 if (isFull(q)) 34 { 35 cout << "Queue is full!" << endl; 36 return; 37 } 38 else 39 { 40 q->rear = q->rear + 1; 41 q->data[q->rear] = data; 42 } 43 }//判断队列是否为空 44 45 46 bool isEmpty(queue Q) 47 { 48 if (Q->front == Q->rear) return true; 49 else return false; 50 }//判断队列是否为满 51 52 53 bool isFull(queue Q) 54 { 55 if (Q->front == (Q->rear + 1) % MAXSIZE) return true; 56 else return false; 57 }//层序遍历
判断末尾叶子结点
1 int* levelOrder(struct Node *T, int root) 2 { 3 int * a = new int[MAXSIZE]; 4 int i = 0; 5 queue q; 6 q = CreateQueue();//q->data[1] = T[root]; 7 addQueue(q, T[root]); 8 while (!isEmpty(q)) 9 { 10 struct Node tmp = deleteQueue(q); 11 a[i++] = tmp.pos; 12 if (tmp.left != '-'&&tmp.left != '-1') 13 { 14 int l = tmp.left - '0'; 15 addQueue(q, T[l]); 16 } 17 if (tmp.right != '-'&&tmp.right != '-1') 18 { 19 int r = tmp.right - '0'; 20 addQueue(q, T[r]); 21 } 22 } 23 return a; 24 }
实践第二题:首先结构体
1 typedef struct{ 2 int doors;//门的数量 3 int *p;//p指向具体门的编号,把p看作是一个整型数组 4 }node;
主函数
1 int main() 2 { 3 //变量的定义 4 node *a;//定义一个动态整型数组 5 int i,j,k,root; 6 7 root=input(a); 8 cout<<find(a,root)<<endl; 9 10 return 0; 11 }
对输入的数字进行整理
1 int input(node *&a) 2 { 3 int n,x,i,j; 4 bool *vi; 5 cin>>n; 6 a=new node[n+1];//为a数组申请空间 7 vi=new bool[n+1]; 8 for(i=1;i<=n;i++)//将vi数组初始化为false 9 vi[i]=false; 10 11 for(i=1;i<=n;++i){ 12 cin>>x; 13 a[i].doors=x; 14 a[i].p=new int[x]; 15 for(j=0;j<x;++j){ 16 cin>>a[i].p[j]; 17 vi[a[i].p[j]]=true; 18 } 19 } 20 //找出根在a数组的下标 21 for(i=1;i<=n;++i) 22 if(!vi[i]) break; 23 24 return i; 25 }
查找出最末尾的叶子结点
1 int find(node *a,int root) 2 {//从a数组的root下标开始 往下搜索 3 queue<int> q;//定义用于存放带访问的门编号的队列 4 //根编号入队 5 q.push(root); 6 int x,i; 7 //当队列不为空 8 //x=出队 9 //x后面的门号入队 10 while(!q.empty()){ 11 x=q.front(); 12 q.pop(); 13 for(i=0;i<a[x].doors;++i) 14 q.push(a[x].p[i]); 15 } 16 //答案就是x 17 return x; 18 }
在这一章中,比较重要的就是树的遍历和查找
树的遍历分为先序遍历(根,左孩子,右孩子),中序遍历(左孩子,根,右孩子),后序遍历(左孩子,右孩子,根)。
二.目标
上周的目标实现了一半,主要就是练习了遍历二叉树和查找叶子结点的有关代码,时间花费还蛮长的,感觉有点难,思路不够清晰
下次的目标:继续多练习代码,加深概念的理解