第五章学习小结

经过了三周的学习,树的内容终于告一段落了,三周的时长也说明了树与二叉树的重要性。

 

树是一种简单的非线性结构。在树这种数据结构中,所有数据元素之间的关系具有明显的层次特性。   在树结构中,每一个结点只有一个前件,称为父结点。没有前件的结点只有一个,称为树的根结点,简称树的根。每一个结点可以有多个后件,称为该结点的子结点。没有后件的结点称为叶子结点。   在树结构中,一个结点所拥有的后件的个数称为该结点的度,所有结点中的度称为树的度。树的层次称为树的深度。

而二叉树,是一种很有用的非线性结构,它具有以下两个特点:1)非空二叉树只有一个根结点;2)每一个结点最多有两棵子树,且分别称为该结点的左子树与右子树。

二叉树作为树中的重点学习内容,自然也有几点衍生内容。

满二叉树:除最后一层外,每一层上的所有结点都有两个子结点。  

完全二叉树:除最后一层外,每一层上的结点数均达到值;在最后一层上只缺少右边的若干结点。

 

二叉树通常采用链式存储结构。

与线性链表类似,用于存储二叉树中各元素的存储结点也由两部分组成:数据域和指针域。但在二叉树中,由于每一个元素可以有两个后件(即两个子结点),因此,用于存储二叉树的存储结点的指针域有两个:一个用于指向该结点的左子结点的存储地址,称为左指针域;另一个用于指向该结点的右子结点的存储地址,称为右指针域。 

 

针对二叉树的操作,比较重要同时也是我认为本章中比较有趣的就是二叉树的遍历了:

(1)前序遍历(DLR):若二叉树为空,则结束返回。否则:首先访问根结点,然后遍历左子树,最后遍历右子树;并且,在遍历左右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。   

(2)中序遍历(LDR):若二叉树为空,则结束返回。否则:首先遍历左子树,然后访问根结点,最后遍历右子树;并且,在遍历左、右子树时,仍然先遍历左子树,然后访问根结点,最后遍历右子树。   

(3)后序遍历(LRD):若二叉树为空,则结束返回。否则:首先遍历左子树,然后遍历右子树,最后访问根结点,并且,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后访问根结点。 

简要概括起来则是:

前序遍历:根左右

中序遍历:左根右

后序遍历:左右根

 

而本章题目中比较记忆深刻的就是天梯赛中的深入虎穴了:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <queue>
 4 using namespace std;
 5 
 6 typedef struct{
 7     int doors;//门的数量 
 8     int *p;//指向后面的门的编号序列 
 9 }node;
10 
11 int input(node *a, int n);
12 int level(node *a, int r);
13 
14 int main(){
15     node *a;//a用于存储整棵树
16     int i, j, k;
17     int n;
18     cin>>n;
19     int root;
20     a = new node[n+1];
21     root = input(a, n);
22     cout<<level(a, root)<<endl;
23     return 0;
24     
25 }
26 
27 int input(node *a, int n){//读入n扇门的信息给a数组,返回根所在的门牌号 下标 
28     int i, j;
29     bool *vi;
30     vi = new bool[n+1];
31     for(i=0; i<n+1; ++i)//初始化vi数组的全部元素为false 
32         vi[i] = false;
33     
34     
35     for(i=1; i<=n; ++i){//读入n扇门的信息 
36         cin>>a[i].doors;
37         if(a[i].doors!=0){
38             a[i].p = new int [a[i].doors];//
39             for(j=0; j<a[i].doors; ++j){
40                 cin>>a[i].p[j];
41                 vi[a[i].p[j]] = true;
42             }//for
43         }//if
44         else//doors为零
45         a[i].p = NULL;
46     } //for
47     
48     for(i=1; i<=n; ++i)//找根结点所在的下标 
49     if(!vi[i]) return i;
50 }
51 
52 int level(node *a, int r){//对a数组进行层次遍历,并返回遍历最后一个结点的编号 
53     queue<int> q;
54     int t, i;
55     q.push(r);
56     
57     while(!q.empty()){
58         t = q.front();
59         q.pop();
60         
61         if(a[t].doors!=0){//t号门后面还有门,后面的门入队
62         for(i=0; i<a[t].doors; ++i)
63         q.push(a[t].p[i]);
64          
65         }
66     }
67  return t;
68 }
View Code

 

本章内容较多也是更为重要,学习过程中遇到的问题相较于前几章也多了不少,但是平心而论,树的学习反倒是个人感觉颇为有趣的一章,同时也是学习了不少新知识,收获颇多,美中不足的就是最后一周因为五一假期的原因学习松散了许多。在接下来的一周要快速调整过来,尽快回复到平时的学习节奏来

posted @ 2019-05-04 23:23  Marshall·Wayne  阅读(160)  评论(4编辑  收藏  举报