zoukankan      html  css  js  c++  java
  • 《数据结构》树与二叉树

      《数据结构》第五章--树与二叉树,我们脱离了线性结构的苦海,来到这个非线性结构的迷雾森林,学习了半个多月,是不是现在还转不过弯来?无论是各种各样的树的遍历方法,还是期末百分之九十九会考的哈夫曼树的最优wpl,都把我们无限眩晕。所以,我们应该怎么过把这种数据结构过关呢?答案是--晕过去。

      皮一下,下面进入正题,开始小结。老规矩,上图,字不好看,请挑选食用。

     

     

    以上就是我的课堂笔记,不过有许多基本的知识还没有在上面,现在补充一下。

    1、树和二叉树是一类具有层次关系的非线性数据结构;总结了一些二叉树容易忘记混淆的基本术语:(1)结点的度:结点拥有的子树树;(2)树的度:树的度是树内各结点度的最大值;(3)层次:结点的层次从根开始定义起,根为第一次,跟单孩子为第二层,以此类推;(4)有序树和无序树:树中结点的个子树从左到右是有次序的(即不能互换)则称为有序树 ,否则为无序树。

    2、二叉树的两种特殊形态:满二叉树完全二叉树。满二叉树是指除了叶子结点,其他结点都是有两个度的二叉树,即一棵深度为k,且有2^k-1个节点的树是满二叉树;完全二叉树是指对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树;

    3、树的遍历我们学了四种,即先序遍历,中序遍历,后序遍历和层次遍历,前三个遍历方法俗称深搜,最后一个则为广搜,四者的时间复杂度都为O(n)

    4、二叉树有两种存储表示:顺序存储和链式存储。顺序存储更适用于完全二叉树。而链式存储又称为二叉链表,链式存储是二叉树的常用存储方式。

    5、树的存储结构有很多种,不过孩子兄弟表示对于树和森林都适用;

    6、树的性质及其他特征在上图中有,在此就不多赘述了。

    再来谈谈解题,选一个我们上机的题吧--7-2 深入虎穴 (30 分)

    其实这题和老师课上讲的思路大抵是一致的,可是到了真刀真枪上战场的时候就GG了,发现自己总是在函数实现上出现问题,虽然停留在本层去解决问题,但是底层的函数如何实现没搞好也是不行的,在上机课的时候跟着老师一步一步走,我觉得还是很有成·成效的,不过有些地方讲的太快,而后又没有去留意,就出现了自己看不懂自己代码的情况。。。

    以下是完整代码:

    #include <iostream>
    #include <queue> 
    
    using namespace std;
    
    typedef struct {
        int doors;//门的数量
        int *p;//指向具体门的编号,把p看作一个整型数组 
    }node;
    
    int input(node *&a);
    int find(node*a,int root);
    
    int  main(){
        //变量定义;
        node *a;//定义一个动态整型数组
        int i,j,k,root;
        
        root=input(a);
        cout<<find(a,root); 
        return 0; 
    }
    
    int input(node *&a)
    {//
        int i,j,x,n;
        cin>>n;
        
        bool *vi= new bool[n+1];//查找根节点
        for(i=1;i<n+1;i++) {
            vi[i]=false; 
        }
        
        a=new node[n+1];//为a数组申请空间 
        
        for(i=1;i<n+1;i++){
            cin>>x;
            a[i].doors=x;
            a[i].p=new int [x+1];
            for(j=1;j<=x;j++){
                cin>>a[i].p[j]; 
                vi[a[i].p[j]]= true;
            }
        }
        
        //找出根在a数组的下标
        for(i=1;i<=n;i++)
            if(!vi[i]) break; 
        return i;
    }
    
    int find(node*a,int root)
    {//层次遍历 ,从a数组的 root下标往下搜索
        int x,j;
        queue<int> q;//定义用于存放待访问的门的编号的队列 
        q.push(root);//根编号入队 
        
        while(!q.empty()){//当队列不为空,x=出队 
            x=q.front();
            q.pop();
            for(j=1;j<=a[x].doors;j++)
                q.push(a[x].p[j]);//x后面的门号入队
            }
        return x;
    } 
        
    
     
    View Code

    我好像没有达到上次立下来的目标(flag),不过这周就开始把题独立做一遍,还有在其他地方做一些比较经典的题目。

    嗯,就这样,拜拜~

  • 相关阅读:
    类的组合
    类的继承和派生
    面向对象编程
    正则表达式
    sys模块 logging模块 序列化模块
    time 模块,random模块,os模块
    递归函数
    interface有没有继承Object
    UTF-8和GBK的区别
    九皇后
  • 原文地址:https://www.cnblogs.com/jyf2018/p/10808554.html
Copyright © 2011-2022 走看看