二叉树建树及遍历的递归和非递归实现

版权声明:莉莉莉 https://blog.csdn.net/qq_41700151/article/details/83512105

1.定义

typedef struct BiTNode
{
    char data;
    struct BiTNode *lchild,*rchild;
} BiTNode,*BiTree;     //BiTree即BiTNode *

2.建树

int CreateBiTree(BiTree &T)   
{
    char data;
    scanf("%c",&data);
    if(data=='#')
        T=NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));     //开辟空间
        T->data=data;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
    return 0;
}

3.前序遍历
即 根左右
1.非递归
在这里插入图片描述
1)对于一个点P,输出节点,入栈,访问其左孩子看是否为空
2)如果不为空,则把他的左孩子当做当前节点,重复1)操作
3)若为空,取栈顶元素,出栈,并将出栈节点的右孩子置为当前节点,看其是否为空;
4)如果为空,此时栈内不为空,则取栈顶元素出栈不输出继续访问其右节点
5)如果不为空,再执行1)操作
6)直到栈内为空并且当前节点为NULL

void PreOrder(BiTree T)
{
    if(T==NULL)
        return ;
    BiTree cur=T;
    stack < BiTree > s;   //定义栈
    while(cur||!s.empty())     //当cur!=NULL说明还有子树可以遍历或者栈不为空时
    {
        while(cur)   
        {
            printf("%c",cur->data);      
            s.push(cur);
            cur=cur->lchild;      
        }
        BiTree topp=s.top();
        s.pop();
        cur=topp->rchild;
    }
    printf("\n");
}

2.递归

void Visit(BiTree T)
{
    if(T->data!='#')
        printf("%c",T->data);
}
void PreOrder(BiTree T)
{
    if(T!=NULL)
    {
        Visit(T);
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    }
}

4.中序遍历
即 左根右
1.非递归
1)取一点P,入栈,访问其左孩子,看是否为空
2)如果不为空,继续进行1)操作
3)如果为空,取栈顶元素,(就是小的左孩子为空的子树的根节点),输出并出栈,访问其右孩子
4)如果为空,此时栈内不为空,取栈顶元素,并将出栈的节点的右孩子置为当前节点,看他是否为空
5)直到当前节点P为NULL并且栈为空,则遍历结束。

void InOrder(BiTree T)
{
    if(T==NULL)
        return ;
    BiTree cur=T;
    stack <BiTree> s;
    while(cur||!s.empty())
    {
        while(cur)
        {
            s.push(cur);
            cur=cur->lchild;
        }
        BiTree topp=s.top();
        printf("%c",topp->data);
        s.pop();
        cur=topp->rchild;
    }
    printf("\n");
}

2.递归

void InOrder(BiTree T)
{
    if(T!=NULL)
    {
        InOrder(T->lchild);
        Visit(T);
        InOrder(T->rchild);
    }
}

5.后序遍历
左右根
1.非递归
1)对于一个节点P,不断访问他的左孩子
2)当左孩子为空时,取栈顶元素,如果他的右子树为空或者他的右孩子被访问过,就输出,并用pos记录下来,出栈,再访问栈顶元素的右孩子反复进行2)操作
3)不满足以上条件时访问他的右孩子,再执行1)

void PostOrder(BiTree T)
{
    BiTree cur=T;
    BiTree pos=T;
    stack<BiTree> s;
    while(cur||!s.empty())
    {
        while(cur)
        {
            s.push(cur);
            cur=cur->lchild;
        }
        BiTree topp=s.top();
        if(topp->rchild==NULL||topp->rchild==pos)  //当右孩子为空或者右孩子已经被访问过
        {
            printf("%c",topp->data);
            pos=topp;
            s.pop();
        }
        else          
        {
            cur=topp->rchild;
        }
    }
    printf("\n");
}

2.递归

void PostOrder(BiTree T)
{
    if(T!=NULL)
    {
        PostOrder(T->lchild);
        PostOrder(T->rchild);
        Visit(T);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41700151/article/details/83512105