第五章学习小结

一.  完成作业或实践时解决困难的经验分享

  这部分讲作业和实践第二题的编程思路。

  作业一:创建根,左孩子,右孩子的结构体

 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 }

在这一章中,比较重要的就是树的遍历和查找

树的遍历分为先序遍历(根,左孩子,右孩子),中序遍历(左孩子,根,右孩子),后序遍历(左孩子,右孩子,根)。

二.目标

上周的目标实现了一半,主要就是练习了遍历二叉树和查找叶子结点的有关代码,时间花费还蛮长的,感觉有点难,思路不够清晰

下次的目标:继续多练习代码,加深概念的理解

 

posted on 2019-05-04 21:12  刘磊w  阅读(123)  评论(2编辑  收藏  举报