二叉树

二叉树是结点的有限集合,这个有限集合或者为空集(称为空二叉树),或者由一个根结点及两棵不相交的、分别称为这个根的左子树和右子树的二叉树组成。
    图5.12所示的是一棵二叉树,根结点为A,其左子树包含结点B、D、G,右子树包含结点C、E、F、H、I。根A的左子树又是一棵二叉树,其根结点为B,有非空的左子树(由结点D、G组成)和空的右子树。根A的右子树也是一棵二叉树,其根结点为C,有非空的左子树(由结点E、H、I组成)和右子树(由结点F组成)。

二叉树

   

    上面介绍的的基本术语在二叉树中同样适用,但需要说明的是,尽管树和二叉树的概念之间有许多关系,但它们是两个概念。二叉树不是树的特殊情况,树和二叉树之间最主要的区别是:二叉树是有序的,二叉树的结点的子树要区分左子树和右子树,即使在结点只有一棵子树的情况下也要明确指出该子树是左子树还是右子树。例如,图5.13中是四棵不同的二叉树,但如果作为树,它们就是相同的了。
                                                    
 图5.12二叉树

    在树与二叉树之间有一个自然的一一对应的关系,每一棵树都能惟一地转换成它所对应的二叉树。把树转换成对应的二叉树的方法是:将树中所有相邻兄弟用线连起来,然后去掉双亲到子女的连线,只留下双亲到第一个子女的连线。对图5.11所示的树用上述方式处理后稍加倾斜,就得到对应的二叉树,
如图5.14所示。
         二叉树

                              图5.13四棵不同的二叉树    二叉树

    满二叉树:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶结点都在同一层上,这样的一棵二叉树称为满二叉树。
    完全二叉树:一棵深度为k的有 n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。显然,一棵满二叉树必定是一棵完全二叉树。
    在图5.15中,图(a)为一棵满二叉树,图(b)为一棵完全二叉树,图(c)为一棵非完全二叉树。

                                                                    图5.14树对应的二叉树

         二叉树

                     图5.15满二叉树、完全二叉树和非完全二叉树

1)先序遍历
void  PreOrder(BiTree root)



    if (root!=NULL)

       {

              Visit(root ->data); 

              PreOrder(root ->LChild); 

              PreOrder(root ->RChild); 

       }

}

               算法 6.1  先序遍历二叉树

2)中序遍历
void  InOrder(BiTree root) 



    if (root!=NULL)

       {

           InOrder(root ->LChild);  

              Visit(root ->data);       

              InOrder(root ->RChild);  

       }

}

               算法 6.2  中序遍历二叉树

3)后序遍历

void  PostOrder(BiTree root) 



    if(root!=NULL)

       {

           PostOrder(root ->LChild);

              PostOrder(root ->RChild);

       }

}


先、中、后序遍历二叉树的非递归算法

1.先序遍历非递归算法
#define maxsize 100
typedef struct
{
    Bitree Elem[maxsize];
    int top;
}SqStack;

void PreOrderUnrec(Bitree t)
{
    SqStack s;
    StackInit(s);
    p=t;
   
    while (p!=null || !StackEmpty(s))
    {
        while (p!=null)             //遍历左子树
        {
            visite(p->data);
            push(s,p);
            p=p->lchild;      
        }//endwhile
       
        if (!StackEmpty(s))         //通过下一次循环中的内嵌while实现右子树遍历
        {
            p=pop(s);
            p=p->rchild;       
        }//endif
               
    }//endwhile
   
}//PreOrderUnrec

2.中序遍历非递归算法
#define maxsize 100
typedef struct
{
    Bitree Elem[maxsize];
    int top;
}SqStack;

void InOrderUnrec(Bitree t)
{
    SqStack s;
    StackInit(s);
    p=t;
    while (p!=null || !StackEmpty(s))
    {
        while (p!=null)             //遍历左子树
        {
            push(s,p);
            p=p->lchild;
        }//endwhile
       
        if (!StackEmpty(s))
        {
            p=pop(s);
            visite(p->data);        //访问根结点
            p=p->rchild;            //通过下一次循环实现右子树遍历
        }//endif  
   
    }//endwhile

}//InOrderUnrec


3.后序遍历非递归算法
#define maxsize 100
typedef enum{L,R} tagtype;
typedef struct
{
    Bitree ptr;
    tagtype tag;
}stacknode;

typedef struct
{
    stacknode Elem[maxsize];
    int top;
}SqStack;

void PostOrderUnrec(Bitree t)
{
    SqStack s;
    stacknode x;
    StackInit(s);
    p=t;
   
    do
    {
        while (p!=null)        //遍历左子树
        {
            x.ptr = p;
            x.tag = L;         //标记为左子树
            push(s,x);
            p=p->lchild;
        }
   
        while (!StackEmpty(s) && s.Elem[s.top].tag==R) 
        {
            x = pop(s);
            p = x.ptr;
            visite(p->data);   //tag为R,表示右子树访问完毕,故访问根结点      
        }
       
        if (!StackEmpty(s))
        {
            s.Elem[s.top].tag =R;     //遍历右子树
            p=s.Elem[s.top].ptr->rchild;       
         
    }while (!StackEmpty(s));
}//PostOrderUnrec

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值