树部分代码练习

一、结构体

typedef struct BiTNode{

        Elemtype data;

        struct BiTNode *lchilde, *rchild;

}BiTNode,*BiTree;

二、二叉树递归遍历

1、先序递归遍历

void preOrder(BiTree T){

        if(T==NULL)

                return;

        else{

                printf("%d",T->data);

                preOrder(T->lchild);

                preOrder(T->rchild);

        }

}

2、中序递归遍历

void InOrder(BiTree T){

        if(T==NULL)

                return ;

        else{

                InOrder(T->lchilde);

                print("%d", T->data);

                InOrder(T->rchild);

        }

}

3、后序递归遍历

void postOrder(Bitree T){

        if(T==NULL)

                return;

        else{

                postOrder(T->lchild);

                postOrder(T->rchild);

                printf("%d",T->data);        

        }

}

三、递归遍历练习

1、利用递归计算二叉树中所有结点的个数
  • 使用全局变量

int n=0;

void Count(BiTree T){

        if(T=NULL)

                return;

        else{

                n++;

                Count(T->lchild);

                Count(T->rchild);

        }

}

  • 使用局部变量

int Count(BTree T){

        int l,r;//l,r是局部变量

        if(T==NULL)

                return 0;

        else{

                l=Count(T->lchild);

                r=Count(T->rchild);

                return l+r+1;

        }

}

2、利用递归计算二叉树中所有叶子结点的个数
  • 全局变量

int n=0;//n是全局变量

void Count(BiTree T){

        if(T=NULL)

                return;

        else{

                if(T->lchild==NULL && T->rchild==NULL)//如果左右孩子都为空,则为叶子结点

                        n++;

                Count(T->lchild);

                Count(T->rchild);

        }

}

  • 局部变量 

 int Count(BiTree T){

        int l,r;

        if(T==NULL)

                return 0;

        else if(T->lchild==NULL && T->rchild==NULL)

                return 1;

        else{

                l=Count(T->lchild);

                r=Count(T->rchild);

                return l+r;

        }

}

3、利用递归计算二叉树中所有双分支结点个数(还需要再看一下)

int Count(BiTree T){

        int l,r;

        if(T=NULL)

                return 0;

        else if(T->lchild!=NULL && T->rchild!=NULL)

                return l+r+1;

        else{

                l=T->lchild;

                r=T->rchild;

                return l+r;

        }

}

四、非递归算法

1、先序非递归

void preOrder(BiTree T){

        Stack s;

        Initstack(s);//初始化栈

        BiTree p=T;//定义遍历指针

        while(p!=NULL || !IsEmpty(s)){

                if(p!=NULL){

                        printf("%d",p->data);

                        push(s,p);

                        p=p->lchild;

                }

                else{

                        pop(s,p);//把栈顶元素弹出,并让p指向它

                        p=p->rchild;

                }//else

        }//while

}//void

2、非递归中序(左根右)

一直遍历到最左边,才打印

void InOrder(BiTree T){

        Stack s;

        Initstack(s);//初始化栈

        BiTree p=T;//定义遍历指针

        while(p!=NULL || !IsEmpty(s)){

                if(p!=NULL){

                        push(s,p);//入栈

                        p=p->lchild;//访问左子树

                }

                else{

                        pop(s,p);//把栈顶元素弹出,并让p指向它

                        printf("%d",p->data);

                        p=p->rchild;//访问右子树

                }//else

        }//while

}//void

3、非递归后序(左右根)

后序会返回两次根,第一次返回根是遍历完左子树之后,为了去遍历右子树;第二次返回根是遍历完右子树之后,为了去遍历根

因此要定义一个记录指针r,用于标记上一个被访问的结点;且在返回根之前判断是为了去遍历右子树,还是为了去遍历根.

每次出栈访问完一个结点就相当于遍历完以该结点为根的子树,需要将p置NULL

void postOrder(BiTree T){

        Stack s;

        InitStack(s);//初始化栈

        BiNode *p=T;

        BiNode *r=NULL;//标记上一个被访问的结点

        while(p!=NULL || !IsEmpty(s)){

                if(p!=NULL){

                        push(s,p);

                        p=p->lchild;

                }

                else{

                        GetTop(s,p);//读栈顶指针,让p指向栈顶结点(非出栈)

                        if(p->rchild!=NULL && p->rchild!=r)//若右子树存在,且未被访问过

                                p=p->rchild;

                        else{

                                pop(s,p);//将该结点弹出

                                printf("%d",p->data);

                                r=p;//记录最近访问过的结点

                                p=NULL;//结点访问完之后,重置p指针

                        }//else

                }//else

        }//while

}//void

4、层序遍历

void LevelOrder(BiTree T){

        InitQueue(Q);

        BiTree p;

        EnQueue(Q,T);//将根节点入队

        while(!IsEmpty(Q)){//队列不空则循环

                DeQueue(Q,p);//队头结点出队

                printf("%d",p->data);

                if(p->lchild!=NULL)

                        EnQueue(Q,p->lchild);

                if(p->rchild!=NULL)

                        EnQueue(Q,p->rchild);

        }

}

五、练习

1、要求二叉树按照二叉链表存储,写一个判别二叉树是否为完全二叉树的算法

bool Is_wqtree(BiTree T){

        IniiQueue(Q);

        EnQueue(Q,T);

        BiTree p;

        while(!IsEmpty(Q)){

                DeQueue(Q,p);

                if(p!=NULL){

                        EnQueue(Q,p->lchild);

                        EnQueue(Q,p->rchild);

                }

                else{

                        while(!IsEmpty(Q)){

                                 DeQueue(Q,p);

                                if(p!=NULL)

                                        return false;

                        }//while

                }else

        }//while

        return true;

}//bool

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值