【数据结构】二叉树遍历

先序遍历和中序遍历非递归代码:

#include <iostream>
#include <vector>
using namespace std;

typedef struct BinaryTree 
{
    int data;
    struct BinaryTree *rchild, *lchild;
}BinaryTree;

int createBinaryTree( BinaryTree * &T)  //必须用引用 因为内存是在函数里面分配的
{
        int ch;
        scanf("%d", &ch);

        if(ch != 0)
        {
            T = (BinaryTree *)malloc(sizeof(BinaryTree));
            T->data = ch;
            createBinaryTree(T->lchild);
            createBinaryTree(T->rchild);
        }
        else
        {
            T = NULL;
        }
    return 0;
}

int visit(int data)
{
    printf("%d ", data);
    return 0;
}


int PreOrderTraverse(BinaryTree T) //先序遍历  
{
    BinaryTree* p;
    vector<BinaryTree *> Stack;
    Stack.push_back(&T);
    while(!Stack.empty())
    {
        while((p = Stack.back()) != NULL) 
        {
            visit(p->data);
            Stack.push_back(p->lchild);
        }
        Stack.pop_back();
        if(!Stack.empty())
        {
            p = Stack.back(); 
            Stack.pop_back();
            Stack.push_back(p->rchild);
        }
    }
    return 0;
}


int InOrderTraverse(BinaryTree T) //中序遍历
{
    BinaryTree* p;
    vector<BinaryTree *> Stack;
    Stack.push_back(&T);
    while(!Stack.empty())
    {
        while((p = Stack.back()) != NULL) 
            Stack.push_back(p->lchild);
        Stack.pop_back();
        if(!Stack.empty())
        {
            p = Stack.back(); 
            Stack.pop_back();
            visit(p->data);
            Stack.push_back(p->rchild);
        }

    }
    return 0;
}

int main()
{
    BinaryTree * T = NULL;
    createBinaryTree(T);
    PreOrderTraverse(*T);
    InOrderTraverse(*T);
    return 0;
}

注意理清楚弹栈的机制。

---------------------------------

今天参考了一下别人的思路 补上后序遍历非递归算法 注意如何设置在右子树弹出时双亲结点的访问和弹出

int AferOrderTraverse(BinaryTree T) //后序遍历
{
    BinaryTree * p;
    vector<BinaryTree *> Stack;
    int tag[30] = {0}; //用tag标签记录存入的是左子树0 还是右子树1
    int tagnum = 0; //记录存放的数量
    Stack.push_back(&T);
    tag[0] = 0;
    tagnum = 1;

    while(!Stack.empty())
    {
        while((p = Stack.back())!= NULL)
        {
            Stack.push_back(p->lchild);
            tag[tagnum++] = 0;
        }
        //只要右子树弹出,其双亲结点就被访问并弹出
        while(tag[tagnum - 1] == 1)  //若是右子树 先弹出开始的空集 访问其parent结点(一定是其上一个结点) 再循环弹出
        {
            Stack.pop_back();
            tagnum--;
            visit(Stack.back()->data);
        }
        Stack.pop_back();
        tagnum--;
    
        if(!Stack.empty())
        {
            p = Stack.back();
            Stack.push_back(p->rchild);
            tag[tagnum++] = 1;
        }
    }
    return 0;
}

 

posted @ 2014-05-16 18:23  匡子语  阅读(233)  评论(0编辑  收藏  举报