数据结构第五章学习小结

.章节概括

       学习了线性结构后,第五章终于开始了一种非线性结构的学习——树,由于树存在的分支关系,我们在遍历树时可以有多种方法,通过本章学习,很好地掌握了先序、中序、后序、层次遍历的方法,它们都无一例外地用到了递归思想。在学习过程中能够感受到这种非线性结构不管是在构建上还是操作上和线性结构区别是很大的,但是分析思想依旧一致。

       二叉树与树的存储结构:

 

 

二、实践深入虎穴

       深入虎穴中,每扇门就相当于树的一个结点,首先要找到根结点,从根结点一层层查找下去,找到最后一个被访问的节点的编号,就是迷宫的最深处。

       于是分析这棵树如何存储的过程就显得十分重要:

     老师带我们从最基础的二维数组的思想入手,判断每种方法都有其可行性的前提下,进一步推想该种方法是否可以继续优化,于是最后确定了指向数组的数组这种方法,可以通过输入的孩子数量K来创建孩子结点,并打包成一个数组,由父结点指向它,节约了存储空间且便于操作。

     输入并查找根结点:该类型操作用途非常广泛,我们在遍历一棵树前要先找出根结点,由根结点查找,我们可以将所有结点都放进一个数组,初始化所有元素为false,每输入一个结点信息就将该结点转为true,这样未输入信息的结点即根结点,就是唯一一个false的结点。

int input(node *a,int n){//读入n扇门的信息给a数组,返回根所在的下标 
    int i,j;
    bool *vi;
    vi=new bool[n+1];
    for(i=1;i<=n;++i)
        vi[i]=false;//初始化vi的全部元素为false;
     
    for(i=1;i<=n;i++){//读入n扇门的信息 
        cin>>a[i].doors;//门的数量
        if(a[i].doors!=0){
            a[i].p=new int[a[i].doors];//为a[i].p申请空间,子树
            for(j=1;j<=a[i].doors;++j) {
                cin>>a[i].p[j-1];//否则发生段错误 
                vi[a[i].p[j-1]]=true;//非根结点 
            }
        
        } 
        else 
        a[i].p=NULL;
    }
    
    for(i=1;i<n;++i){
        if(!vi[i])
        return i;
    }
}

层次遍历找出最后一个遍历的结点编号:

 

int level(node *a,int r){//从a[r]开始对a进行层次遍历,并返回最后一个节点的编号 
    int i,t;
    queue<int> q;
    q.push(r);
    
    while(!q.empty()){
        t=q.front();
        q.pop();
        
        if(a[t].doors!=0){//t号门后面还有门,后面的门入队 
           for(i=0;i<a[t].doors;++i)
              q.push(a[t].p[i]);
        }
    }
    return t;//随着不断访问,之前数据被覆盖,最后被访问的结点就是t 
}

 

 

三、总结

本章学习收获很多,学会了如何用多种顺序遍历一棵二叉树,如何查找根结点,并在老师的带领下学会如何让进一步分析树的最方便的存储结构,在需要老师的带领下做得很轻松,自己再来打有些吃力,在做树的同构这道题目上还是出现了比较大的障碍,很大部分查找了网上的代码才完成,主要原因是对递归思想掌握不够好,希望能够多花点时间分析一下递归思想,能够自主完成这个题目。

 

 

     

 

posted on 2019-05-04 12:17  King--  阅读(256)  评论(2编辑  收藏  举报

导航