二叉树的基础操作

/*遍历有伪代码*/
/*二叉树的遍历*/
#include<bits/stdc++.h>
using namespace stdl;
#define OK 1
#define ERROR -1
#define OVERFLOW -2
typedef int BElemType;
typedef int Status;
typedef struct BTNode
{
    BElemType data;
    struct BTNode* lchild;
    struct BTNode* rchild;
    struct BTNode* node;
    bool   isfirst;


} BTNode,*BiTree;
//求叶子数
int GetNumberofleaf(BiTree T)
{
    //如果是空树就返回0
    if(T==NULL)
        return 0;
    //只要没有左孩子和右孩子就加一
    if(!T->lchild&&!T->rchild)
    return 1;
    //有左孩子和右孩子就一直向下走
    else
        return GetNumberofleaf(T->lchild)+GetNumberofleaf(T->rchild);
}

//求节点数
int GetNumberofNode(BiTree T)
{
    //如果是一个空树就返回0
  if(T==NULL)
    return 0;
    //不是空树就返回左孩子的结点数加右孩子的结点数
  else
    return 1+GetNumberofNode(T->lchild)+GetNumberofNode(T->rchild);
}

//求深度
int GetDepth(BiTree T)
{
    if(!T)
        return 0;
    else
    {
        int d1=1+GetDepth(T->lchild),d2=1+GetDepth(T->rchild);
        return d1>d2?d1:d2;

    }
}

//销毁
Status DestroyBiTree(BiTree &T)
{
    if(!T)
        return OK;
    else
    {
        DestroyBiTree(T->lchild);
        DestroyBiTree(T->rchild);
        free(B);
        B=NULL;

    }

}
//递归初始化
Status CreatBiTree(BiTree &T)
{
    TElemType e;
    cin>>e;
    if(!e)
    return OK;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        if(!T)exit(OVERFLOW);
        T->data=e;
        CreatBiTree(T->lchild);
        CreatBiTree(T->rchild);
        return OK;
    }
}



//递归方法实现的周游路径完全相同//输出不同序的递归是因为输出的结点不对
Status PreOrderTraversal(BiTree T)
{
    if(!T)
        return OK;
    else
    {
        cout<<T->data;
        PreOrderTraversal(T->lchild);
        PreOrderTraversal(T->rchild);
        return OK;
    }
}

//非递归方法实现中序遍历
//主体流程是先把根入栈,一直访问左子树,出栈,有右子树,进入新一轮循环
//关键是一直左走,退到二叉树中间的元素,转到右边,重新进入循环
Status InOrderTraversal(BiTree T)
{
    while(T||!isEmpty(S))//非空执行找左子树找右子树操作,栈不为空执行出栈并找右子树操作
    {
        while(T)
        {
            Push(S,T);
            T=T->lchild;
        }
        if(!isEmpty(S))
        {
            T=Pop(S);
            cout<<T->data<<endl;
            T=T->rchild;
        }
    }
}

//先序遍历的非递归
//因为前中后遍历的顺序完全一样,只是输出的顺序不一样
Status PreOrderTraversal(BiTree T)
{
    stack S;
    while(T||!isEmpty(S))
    {

        while(T)
        {
            Push(T);
            cout<<T->data<<endl;
            T=T->lchild;
        }
        if(!isEmpty(S))
        {
            T=Pop(S);
            T=T->rchild;
        }

    }
}

//后序遍历的非递归实现/*两个栈*/
//要保证左子树和右子树都被访问完了才能访问
//输出的要求:根节点在栈底,右结点在栈中,左结点在栈顶。
//循环
//每次结点直接入栈1,循环条件是栈1不为空,从栈1出栈之后进入栈2

Status PostOrderTraversal(Bitree T)
{
    stack S1,S2;
    BiTree p,q;
    Push(S1,T);
    while(!isEmpty(S1))
    {
        p=Pop(S1);//栈1里面出来一个
        Push(S2,p);//从栈1出栈进入栈2
        if(q->lchild)//向左走
        {
            Push(S1,q->lchild);
        }
        if(q->rchild)//向右走
        {
            Push(S1,q->rchild);
        }

    }
    while(!isEmpty(S2))//现在栈2顺序就是后序
    {
        q=Pop(S2);
        cout<<q->data<<endl;
    }
}

//后序遍历非递归/*找到第二次遇到的时候输出*/
//在结构体中需要加一个flag判断是第几次遇到的结点
Status PostOrderTraversal(BiTree T)
{
    stack S;
    BiTree p=T;
    BiTree t;
    while(p||!isEmpty(S))
    {
        while(p)//一直往左走
        {
            BiTree c=(BiTree)malloc(sizeof(BTNode));
            c->node=p;
            c->isfirst=true;//进栈是第一次遇到
            Push(S,c);
            p=p->lchild;
        }
        if(!isEmpty(S))//走到左边头上了
        {
            t=Pop(S);//开始出栈
            if(t->isfirst)//出栈的时候是第二次遇到
            {
                t->isfirst=false;
                Push(S,t);//入栈
                p=t->rchild;//向右边走
            }
            else
            {
                cout<<t->data<<endl;//又一次遇到是第三次遇到了直接输出。
                p=NULL;
            }
        }


    }
}

//层序遍历
//二叉树遍历要解决的问题:访问左子树之后你要找到根节点,继续找到右子树
//队列的应用
Status LevelOrderTraversal(BiTree T)
{
    Queue Q;
    BiTree f;
    if(!T)return OK;//如果是空树就返回OK
    CreateQueue(Q);
    EnQueue(Q,T);//先让跟入队
    while(!isEmpty(Q))//只要队里面还有元素
    {
        f=DeQueue(Q);//让最前面的出来并输出
        cout<<f->data<<endl;
        if(f->lchild)EnQueue(Q,f->lchild);//让左右儿子入队
        if(f->rchild)EnQueue(Q,f->rchild);
    }
    return OK;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值