二叉树的遍历

来源:互联网 发布:junit数据库自动回滚 编辑:程序博客网 时间:2024/06/15 16:06

多种方式遍历二叉树
遍历二叉树最简单的是使用递归,如果使用栈也不是很难,不过许久没用都忘记的差不多了。花了一些时间做了整理,方便以后查阅,也希望有人能用到。

typedef struct TreeNode{    char data;    struct TreeNode* left;    struct TreeNode* right;}BiTree,*PBiTree;typedef struct STACK{    PBiTree tree;       //栈元素为指向二叉树节点的指针    bool flag;          //后续遍历时会用到该标示    struct STACK* link; //栈节点链指针}STACK,*PSTACK;void pop(PSTACK& pstack,PBiTree& treeNode){    if (pstack == NULL)    {        treeNode = NULL;    }    else    {        treeNode = pstack->tree;        PSTACK delNode = pstack;        pstack = pstack->link;   //栈顶指向下一个链接        free(delNode);           //释放栈顶节点        delNode = NULL;    }}void push(PSTACK& pstack,PBiTree treeNode){    if (treeNode)    {        PSTACK newNode = (PSTACK)malloc(sizeof(STACK));        if (newNode == NULL)        {            exit(-1);        }        newNode->tree = treeNode;        newNode->link = pstack;        pstack = newNode;    }}void InitTree(PBiTree& Tree){    char ch;        cin>>ch;    if (ch == '#')    {        Tree = NULL;        return;    }    else    {        Tree = (PBiTree)malloc(sizeof(BiTree));        if (Tree == NULL)        {            exit(-1);        }        Tree->data = ch;        cout<<"输入"<<ch<<"结点的左子节点:"<<endl;        InitTree(Tree->left);        cout<<"输入"<<ch<<"结点的右子节点:"<<endl;        InitTree(Tree->right);    }}//销毁树void DeleteTree(PBiTree& tree){    if (tree)    {        DeleteTree(tree->left);        DeleteTree(tree->right);        free(tree);        tree = NULL;    }}//前序遍历 递归void re_Preorder(PBiTree& tree){       if (tree)    {        cout<<tree->data<<" ";        re_Preorder(tree->left);        re_Preorder(tree->right);    }}//中序遍历 递归void re_Midorder(PBiTree& tree){       if (tree)    {               re_Midorder(tree->left);        cout<<tree->data<<" ";        re_Midorder(tree->right);    }}//后序遍历 递归void re_Postorder(PBiTree& tree){       if (tree)    {           re_Postorder(tree->left);        re_Postorder(tree->right);        cout<<tree->data<<" ";     }}//前序遍历 栈void st_Preorder(PBiTree tree){    PSTACK pstack = NULL;    while (tree)    {        cout<<tree->data<<" ";        if (tree->right)//右子树入栈        {            push(pstack,tree->right);        }        if (tree->left) //左子树入栈        {            push(pstack,tree->left);        }        pop(pstack,tree);    }}//中序遍历 栈void st_Midorder(PBiTree tree){    PSTACK pstack = NULL;    while(tree || pstack)    {        while (tree)            //将所有左子树入栈        {               push(pstack,tree);            tree = tree->left;        }        if (pstack)        {            pop(pstack,tree);       //树节点出栈            cout<<tree->data<<" ";  //访问节点            tree = tree->right;     //访问节点的右子树节点        }    }}//后序遍历 栈void st_Postorder(PBiTree tree){    PSTACK pstack = NULL;    do     {        while (tree)        {            push(pstack,tree);            pstack->flag = false;   //右子树未访问            tree = tree->left;      //左子树入栈        }        if (pstack)        {            while (pstack&&pstack->flag)//节点右子树已经访问 访问该节点            {                pop(pstack,tree);                cout<<tree->data<<" ";            }            if (pstack)            {                pstack->flag=true;  //置右子树访问标示为真                tree = pstack->tree->right;             }        }    } while (pstack);}void main(){    PBiTree tree = NULL;        cout<<"请输入根节点元素,#表示无:"<<endl;    InitTree(tree);    cout<<"================递归遍历================="<<endl;    cout<<"前序遍历:";    re_Preorder(tree);    cout<<endl<<"中序遍历:";    re_Midorder(tree);      cout<<endl<<"后序遍历:";    re_Postorder(tree);    cout<<endl<<"================链栈遍历================="<<endl;    cout<<"前序遍历:";    st_Preorder(tree);    cout<<endl<<"中序遍历:";    st_Midorder(tree);    cout<<endl<<"后序遍历:";    st_Postorder(tree);    DeleteTree(tree);    return;}

运行结果:
这里写图片描述

原创粉丝点击