数据结构||第五章小结

       本章主要学习了树和二叉树相关知识,包括二叉树的性质和存储结构(双亲表示法、孩子表示法、孩子兄弟法),二叉树的前、中、后序遍历算法等,还了解了哈夫曼树和哈夫曼编码的构造方法,以及森林与二叉树之间的相互转换方法。

         实验课老师带领我们做了“深入虎穴”这道题:

7-2 深入虎穴 (30 分)

著名的王牌间谍 007 需要执行一次任务,获取敌方的机密情报。已知情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门。每一扇门背后或者是一个房间,或者又有很多条路,同样是每条路通向一扇门…… 他的手里有一张表格,是其他间谍帮他收集到的情报,他们记下了每扇门的编号,以及这扇门背后的每一条通路所到达的门的编号。007 发现不存在两条路通向同一扇门。

内线告诉他,情报就藏在迷宫的最深处。但是这个迷宫太大了,他需要你的帮助 —— 请编程帮他找出距离入口最远的那扇门。

输入格式:

输入首先在一行中给出正整数 N(<),是门的数量。最后 N 行,第 i 行(1)按以下格式描述编号为 i 的那扇门背后能通向的门:

K D[1] D[2] ... D[K]

其中 K 是通道的数量,其后是每扇门的编号。

输出格式:

在一行中输出距离入口最远的那扇门的编号。题目保证这样的结果是唯一的。

输入样例:

13
3 2 3 4
2 5 6
1 7
1 8
1 9
0
2 11 10
1 13
0
0
1 12
0
0

输出样例:

12

       跟上节课讲题思路一样,首先考虑数据结构,根据一个门后面又有很多门,自然就联想到“树”的结构,而每扇门都能包含其所通向的门的信息,即要存储每个结点的孩子结点的信息,老师一开始采用的是二维数组来存储,思考后发现这是一个稀疏矩阵,会导致大量空间的浪费。因此为了避免浪费空间,可以采用结构体数组的方式,结构体数组由数据域(通向的门的个数)和指针域(通向的门的编号)组成。

1 typedef struct{
2     int doors;//门的数量
3     int *p;//指向后面的门的编号序列 
4 }node;
View Code

 

       代码由多个实现不同功能的函数构成。

  1. 读入门的信息,返回根所在的门牌号
     1 int Input(node *a, int n){//读入n扇门的信息给a数组,返回根所在的门牌号(下标) 
     2     int i,j;
     3     bool *vi;
     4     vi=new bool[n+1];
     5     for(i=1;i<=n;++i)//初始化vi数组的全部元素为false 
     6         vi[i]=false; 
     7     for(i=1;i<=n;++i){//读入n扇门的信息
     8         cin>>a[i].doors;
     9         if(a[i].doors!=0){
    10             a[i].p=new int[a[i].doors];//为a[i].p申请空间 
    11             for(j=1;j<=a[i].doors;++j){
    12                 cin>>a[i].p[j-1]; 
    13                 vi[a[i].p[j-1]]=true;
    14             } 
    15         }
    16         else//doors为0 
    17             a[i].p=NULL;
    18     }
    19     for(i=1;i<=n;++i)//找根节点所在的下标 
    20         if(!vi[i]) return i; 
    21 }
    View Code
  2. 利用层次遍历得到树最深的结点,返回遍历的最后一个节点的编号
     1 int Level(node *a, int r){//从a[r]开始对a进行层次遍历,并返回遍历的最后一个节点的编号 
     2     queue<int> q;
     3     int t;
     4     q.push(r);
     5     while(!q.empty()){
     6         t=q.front();
     7         q.pop();
     8         if(a[t].doors!=0){//t号门后面还有门,后面的门入队
     9             for(int i=0;i<a[t].doors;++i)
    10                 q.push(a[t].p[i]);
    11         }
    12     }
    13     return t;
    14 }
    View Code
  3. 最后是主函数
     1 int main(){
     2     node *a;//a用于存储整棵树
     3     int i,j,k;
     4     int n,root;
     5     cin>>n;
     6     a=new node[n+1];
     7     root=Input(a,n);
     8     cout<<Level(a,root)<<endl;
     9     return 0;
    10 }
    View Code

 

 

       这次实验课后,感觉自己思考、入手问题的能力有所加强,分析问题能力也有所提高,但是打代码的能力还是比较弱,因此还是要自己多多练习,另外本章的概念比较多也难懂,要再多花时间看看书本,熟悉所有概念。

posted @ 2019-05-04 23:30  .Daylight  阅读(264)  评论(1编辑  收藏  举报