zoukankan      html  css  js  c++  java
  • 二叉树的递归遍历,非递归遍历,层次遍历.

            闲来无事,写写二叉树的非递归遍历,层次遍历和递归遍历.特别是那个非递归后序遍历,更加深了我的理解.创建二叉树,采用先序递归方法,结点数据类型为char型.原程序在vim下编辑,格式不是太好,多多见谅,在此贴出,期望大家共同找BUG.

    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>

    using namespace std;

    typedef struct tree
    {
    char data;
    struct tree *lchild;
    struct tree *rchild;
    }Tnode,*Tree;

    //递归先序遍历.
    void prePrint(Tree bt)
    {
    if(bt!=NULL)
    {
    cout<<bt->data;
    prePrint(bt->lchild);
    prePrint(bt->rchild);
    }
    }

    //递归中序遍历.
    void orderPrint(Tree bt)
    {
    if(bt!=NULL)
    {
    orderPrint(bt->lchild);
    cout<<bt->data;
    orderPrint(bt->rchild);
    }
    }

    //递归后序遍历.
    void postPrint(Tree bt)
    {
    if(bt!=NULL)
    {
    postPrint(bt->lchild);
    postPrint(bt->rchild);
    cout<<bt->data;
    }
    }

    //非递归先序遍历.
    void preNormPrint(Tree bt)
    {
    Tree stackTree[100];
    int top=-1;
    while(top>-1||bt!=NULL)
    {
    if(bt==NULL)
    bt=stackTree[top--];
    /**
    第一次访问时即遍历.
    将该结点的右子树加入栈中.
    继续遍历左子树.
    **/
    cout<<bt->data;
    if(bt->rchild!=NULL)
    stackTree[++top]=bt->rchild;
    bt=bt->lchild;
    }
    }

    //非递归中序遍历二叉树.
    void NRorderPrint(Tree bt)
    {
    Tree stackTree[100];
    int top=-1;
    while(top>-1||bt!=NULL)
    {
    while(bt!=NULL)
    {
    stackTree[++top]=bt;
    bt=bt->lchild;
    }
    /**
    第二次访问该结点时遍历.
    将左子树加入栈中,等待第二次访问.
    遍历左子树之后,遍历右子树.
    **/
    bt=stackTree[top--];
    cout<<bt->data;
    bt=bt->rchild;
    }
    }

    //非递归后序遍历.
    void NRpostPrint(Tree bt)
    {
    Tree stackTree[100];
    int top=-1;
    int visit[100]; //记录第几次访问.
    memset(visit,0,sizeof(visit)); //全部初始化为0.
    while(top>-1||bt!=NULL)
    {
    if(bt==NULL)
    {
    //当第三次访问时遍历.如果访问到这个地方,必然是第三次.
    bt=stackTree[top];
    //第三次访问,从右子树向根的方向上访问.
    visit[top]++; //可以和下面合写为if(visit[top]==2)
    if(visit[top]==3)
    {
    cout<<bt->data;
    //下面这个必须要小心了,由于是栈的形式,后面可能还会用到,要清零.
    visit[top]=0;
    top--;
    }
    if(top==-1) //为了退出程序.break也可以.
    bt=NULL;
    }
    else
    {
    while(bt!=NULL)
    {
    stackTree[++top]=bt;
    visit[top]++; //第一次访问,从中间方向.
    bt=bt->lchild;
    }
    }

    if(top>-1)
    {
    bt=stackTree[top];
    if(visit[top]==1)
    {
    visit[top]++;//第二次访问,从左子树向根的方向访问.
    bt=bt->rchild;
    }
    else
    bt=NULL;
    /*
    此处需要认真理解.
    */
    }
    }
    }

    //层次遍历.
    void layerPrint(Tree bt)
    {
    Tree queueTree[100];
    int head,tail;
    head=-1,tail=-1;
    if(bt!=NULL)
    queueTree[++tail]=bt;
    while(tail>head)
    {
    bt=queueTree[++head];
    cout<<bt->data;
    if(bt->lchild!=NULL)
    queueTree[++tail]=bt->lchild;
    if(bt->rchild!=NULL)
    queueTree[++tail]=bt->rchild;
    }
    }

    //递归创建二叉树.
    void createTree(Tree &bt)
    {
    char ch;
    ch=getchar();
    if(ch==' ')
    bt=NULL;
    else
    {
    bt=(Tree)malloc(sizeof(Tnode));
    if(bt==NULL)
    exit(1);
    bt->data=ch;
    createTree(bt->lchild);
    createTree(bt->rchild);
    }
    }


    int main()
    {
    Tree bt;
    createTree(bt);
    cout<<"递归先序遍历:"<<endl;
    prePrint(bt);
    cout<<endl;
    cout<<"非递归先序遍历:"<<endl;
    preNormPrint(bt);
    cout<<endl;
    cout<<"递归中序遍历:"<<endl;
    orderPrint(bt);
    cout<<endl;
    cout<<"非递归中序遍历:"<<endl;
    NRorderPrint(bt);
    cout<<endl;
    cout<<"递归后序遍历:"<<endl;
    postPrint(bt);
    cout<<endl;
    cout<<"非递归后序遍历:"<<endl;
    NRpostPrint(bt);
    cout<<endl;
    cout<<"层次遍历:"<<endl;
    layerPrint(bt);
    cout<<endl;
    return 0;
    }




  • 相关阅读:
    剑指Offer——矩形覆盖
    剑指Offer——变态跳台阶
    ASCII table and description .
    字符编解码的故事(ASCII,ANSI,Unicode,Utf-8区别) .
    tchar 输入输出类 和 string 类 函数简单说明 总结各种前缀后缀
    各种 C++编译器的性能对比
    怎样写参数个数可变的宏 Debug宏 Log宏等
    C语言中的可变参数函数 三个点“…”printf( const char* format, ...)
    常用C语言字符串操作函数
    Multi-Byte Character Set &amp; Use Unicode Character Set .
  • 原文地址:https://www.cnblogs.com/wmx3ng/p/2775950.html
Copyright © 2011-2022 走看看