第五章学习小结

  树是一种非线性结构,除它的基本定义和基本术语,我们还要学会其相关性质,其中以二叉树的性质为例:性质1 在二叉树的第i层上至多有2i-1个节点(i>=1);性质2 深度为k的二叉树至多有2k-1个结点(k>=1)性质3 对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1.

  然后到了遍历二叉树,回顾二叉树的递归定义可知,二叉树是由3个基本单位组成:根节点、左子树和右子书。

  1.先(根)序遍历的递归算法定义:
  若二叉树非空,则依次执行如下操作:
  ⑴ 访问根结点;
  ⑵ 遍历左子树;
  ⑶ 遍历右子树。

 

  2.中(根)序遍历的递归算法定义:
  若二叉树非空,则依次执行如下操作:
  ⑴遍历左子树;
  ⑵访问根结点;
  ⑶遍历右子树。

 

  3.后(根)序遍历得递归算法定义:
  若二叉树非空,则依次执行如下操作:
  ⑴遍历左子树;
  ⑵遍历右子树;
  ⑶访问根结点。

然后来说一下这次作业的树的同构

 

int Di(int x,int y)
{//判断同构 
    if(x==-1&&y==-1)
        return 1;
    if(((x == -1)&&(y != -1)) || ((x!=-1)&&(y == -1)))
        return 0;
    if((t1[x].num)!=(t2[y].num))
        return 0;
    if((t1[x].lch==-1)&&(t2[y].lch==-1))
        return Di(t1[x].rch,t2[y].rch); 
    if(((t1[x].lch!=-1)&&(t2[y].lch!=-1))&&((t1[t1[x].lch].num)==(t2[t2[y].lch].num))) 
        return(Di(t1[x].lch,t2[y].lch)&&Di(t1[x].rch,t2[y].rch));
    //如果两棵树左孩子(一个为空一个不空或者都不空)并且数据不一样,那么判断第一节树的左(右)孩子是否跟第二棵树的右(左)孩子同构
    else
        return(Di(t1[x].lch,t2[y].rch)&&Di(t1[x].rch,t2[y].lch));
}

然后是深入虎穴,这其中我学会了一些queue头文件的知识,代码如下:

#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;//a[]可大可小,所以将它变成一个动态整型数组
    int i,j,root;
    root = input(a);
    cout<<find(a,root)<<endl;//从root开始,一层层往下遍历
    return 0; 
} 
int input(node *&a)
{
    int N;//一共有N扇门,在第一行输出
    cin>>N;
    int i,j,number;    
    bool *vi;
    vi = new bool[N+1];//为了后续判断是否为根节点 
    a = new node[N+1];   
    for(i=1;i<=N;i++)
    {
        vi[i] = false;//将vi数组初始化为false 
    }    
    for(i=1;i<=N;++i)
    {
       cin >> number;//每扇门后的通道总数        
       a[i].doors = number;       
       a[i].p = new int[number];//每扇门后面对应的门牌号,构成一个数组
    //放若干个int,new的 有效空间是number+1,如果是number 后面j就要从0开始     
       for(j=0;j<number;++j)
       {
              cin >> a[i].p[j];     
            vi[a[i].p[j]] = true; 
            //满足此循环条件的,即number>=1的,就将vi[a[i].p[i]]赋为true,即编号为a[i].p[i]的不为根节点
        }         
    }     
    for(i=1;i<=N;++i)
       if(!vi[i]) break;
       return i; 
} 
int find(node *a,int root)
{//从数组的root下标开始往下搜索 
    queue<int> q;//定义用于存放待访问的门编号的队列     
    q.push(root);//根编号入队     
    int x,i;
    while(!q.empty())
    {//当队列不为空的时候
        x = q.front();//x在最前面,为出队 
        q.pop();//最后一个出队的就是最后一个进队的 就是最深处的那个 
        if(x!=0)
        {
            for(i=0;i<a[x].doors;i++)
            {
               q.push(a[x].p[i]);
            }     
        }      
    } 
    return x;     
}

上周的学习目标没有完成,这周打算复习一下第四章和第五章

posted @ 2019-05-04 16:30  杨玉翔  阅读(225)  评论(1编辑  收藏  举报