数据结构复习(一)二叉树的前中后序遍历(递归,非递归)以及层次遍历

二叉树的前中后序遍历(递归,非递归)以及层次遍历

二叉树的定义

typedef struct BTNode
{
    int data;
    struct BTNode *lchild,*rchild;
}BTNode,*BiTree;

先序遍历

void PreOrder(BiTree T) //递归法
{
    if(T!=NULL)
    {
        cout<<T->data<<" ";
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    }
}
void PreOrder_2(BiTree T) //非递归法
{
    stack<BiTree> S;
    BiTree p=T;
    while(p||!S.empty())
    {
        if(p)
        {
            cout<<p->data<<" ";
            S.push(p);
            p=p->lchild;
        }
        else
        {
            p=S.top();
            S.pop();
            p=p->rchild;
        }
    }
}

中序遍历

void InOrder(BiTree T) //递归法
{
    if(T!=NULL)
    {
        InOrder(T->lchild);
        cout<<T->data<<" ";
        InOrder(T->rchild);
    }
}
void InOrder_2(BiTree T) //非递归法
{
    stack<BiTree> S;
    BiTree p=T;
    while(p||!S.empty())
    {
        if(p)
        {
            S.push(p);
            p=p->lchild;  //找到最左结点
        }
        else
        {
            p=S.top();
            cout<<p->data<<" ";
            S.pop();
            p=p->rchild;
        }
    }
}

后序遍历

void PostOrder(BiTree T) //递归法
{
    if(T!=NULL)
    {
        PostOrder(T->lchild);
        PostOrder(T->rchild);
        cout<<T->data<<" ";
    }
}

后序遍历的递归算法很好想,但是非递归算法相比于先序和中序非递归算法来说复杂一点,具体的思路是这样的:
总体:先访问左子树,再访问右子树,最后访问根节点。

首先从根节点开始,将根结点入栈,然后沿着左子树一直找到最左的那个结点。但注意,此时不能出栈,因为要判断是否该结点的父亲结点有右子树。若该结点的父亲结点有右子树,那么要按相同的规则对这个右子树进行处理,直到处理不下去为止。
如果栈顶元素要出栈,那么一定是右子树为空或者右子树被访问过,所以下面代码里加入了一个辅助指针r,用来指向最近访问过的结点。

void PostOrder_2(BiTree T)
{
    stack<BiTree> S;
    BiTree p=T;
    BiTree r=NULL;//辅助指针,指向最近访问过的结点

    while(p||!S.empty())
    {
        if(p)
        {
            S.push(p);
            p=p->lchild;  //一直找到最左的结点
        }
        else
        {
            p=S.top(); //读栈顶元素,但不出栈
            if(p->rchild!=NULL&&p->rchild!=r) //如果右子树存在,且未被访问过
            {
                p=p->rchild;  //指向右孩子
                S.push(p); //压入栈内
                p=p->lchild; //再去找最左结点
            }
            else
            {
                cout<<p->data<<" "; //访问该结点
                r=p; //记录最近访问的结点
                S.pop(); //弹出栈顶结点
                p=NULL; //访问完此结点后,重置p指针
            }
        }
    }
}

层次遍历

void LevelOrder(BiTree T)
{
    queue<BiTree> Q;
    BiTree p=T;
    Q.push(p); //头结点入队
    while(!Q.empty())
    {
        p=Q.front();
        cout<<p->data<<" ";
        Q.pop();  //出队
        if(p->lchild)
        {
            Q.push(p->lchild);
        }
        if(p->rchild)
        {
            Q.push(p->rchild);
        }
    }
}

建立二叉树

我用的是二叉排序树的建立方法

void AddBTNode(int num)
{
    BTNode *newNode=(BTNode*)malloc(sizeof(BTNode));
    newNode->data=num;
    newNode->lchild=NULL;
    newNode->rchild=NULL;

    BiTree curNode;
    int flag=0;

    if(bTree==NULL)  //此处bTree是全局变量
    {
        bTree=newNode;
    }
    else
    {
        curNode=bTree;
        while(!flag) //flag==1时表示结点已插入
        {
            if(num<curNode->data)
            {
                if(curNode->lchild==NULL)
                {
                    curNode->lchild=newNode;
                    flag=1;
                }
                else
                {
                    curNode=curNode->lchild;
                }
            }
            else
            {
                if(curNode->rchild==NULL)
                {
                    curNode->rchild=newNode;
                    flag=1;
                }
                else
                {
                    curNode=curNode->rchild;
                }
            }
        }
    }
}

总体执行程序

int main()
{
    //5 3 4 8 7 9
    int a[6];
    int i=0;
    cout<<"输入6位数:"<<endl;
    for(i=0;i<6;i++)
    {
        cin>>a[i];
    }
    for(i=0;i<6;i++)
        AddBTNode(a[i]);
    cout<<"递归前序遍历:"<<endl;
    PreOrder(bTree);
    cout<<endl;
    cout<<"非递归前序遍历:"<<endl;
    PreOrder_2(bTree);
    cout<<endl;
    cout<<"递归中序遍历:"<<endl;
    InOrder(bTree);
    cout<<endl;
    cout<<"非递归中序遍历:"<<endl;
    InOrder_2(bTree);
    cout<<endl;
    cout<<"递归后序遍历:"<<endl;
    PostOrder(bTree);
    cout<<endl;
    cout<<"非递归后序遍历:"<<endl;
    PostOrder_2(bTree);
    cout<<endl;
    cout<<"层次遍历:"<<endl;
    LevelOrder(bTree);
    cout<<endl;
    return 0;
}

运行结果:
二叉树4种遍历的运行结果

发布了5 篇原创文章 · 获赞 11 · 访问量 146

猜你喜欢

转载自blog.csdn.net/AndreyFC/article/details/105227877