非递归遍历树

来源:互联网 发布:淘宝店入驻折800 编辑:程序博客网 时间:2024/05/17 22:11

花了很久完成了这个非递归实现树的遍历的代码,中间在堆栈的使用方面出了一些问题,耽误了很久,最后在后序遍历上也纠结了很久。现在,把代码分享一下:

/* ************************************************ *Name : Bittree all operation *Date : 2014-12-18 *Author : marksman *Aim : Create a bittree and visit it. ************************************************ */#include <stdio.h>#include <stdlib.h>#define stack_size 100/* *Tree structure */typedef struct{   char data;   struct tree *lchild,*rchild;}tree,*Bit_tree;/* *Create the bittree */Bit_tree Create_bit_tree(Bit_tree bittree){    char ch;    scanf("%c",&ch);    getchar();    if(ch=='$')        bittree = NULL;    else    {        bittree = (tree *)malloc(sizeof(tree));        bittree->data = ch;        bittree->lchild = Create_bit_tree(bittree->lchild);        bittree->rchild = Create_bit_tree(bittree->rchild);    }    return bittree;}/* *preorder the bittree */int preorder_bit_tree(Bit_tree bittree){    if(bittree)    {        printf("%c ",bittree->data);        preorder_bit_tree(bittree->lchild);        preorder_bit_tree(bittree->rchild);    }    return 0;}/* *inorder the bittree */int inorder_bit_tree(Bit_tree bittree){    if(bittree!=NULL)    {        inorder_bit_tree(bittree->lchild);        printf("%c ",bittree->data);        inorder_bit_tree(bittree->rchild);    }    return 0;}/* *beorder the bittree */int beorder_bit_tree(Bit_tree bittree){    if(bittree!=NULL)    {        beorder_bit_tree(bittree->lchild);        beorder_bit_tree(bittree->rchild);        printf("%c ",bittree->data);    }    return 0;}/* *build a Immoblization bottom stack *Push order is from bottom to top */typedef struct{    int top;    int bottom;    tree *buf[stack_size];}stack,*stack_point;/* *Operation of stack */ /*  *Initiablization of stack  */stack_point init_stack(stack_point stp){    stp = (stack *)malloc(sizeof(stack));    stp->top = 0;    stp->bottom = stp->top;    return stp;}/* *Push of stack */void push(stack_point stp,Bit_tree bittree){    if(stp->top>=stack_size)    {        printf("stack overflow!\n");        return 1;    }    stp->buf[stp->top] = (tree *)malloc(sizeof(tree));    stp->buf[stp->top] = bittree;    stp->top++;}/* *Pop of stack */Bit_tree pop(stack_point stp){    stp->top--;    return stp->buf[stp->top];}/* *stack status */int stack_status(stack_point stp){    if(stp->top ==0 && stp->bottom == stp->top)    {        return 1;    }    return 0;}/* *top of stack */Bit_tree stack_top(stack_point stp){    if (stp->top<=0)        return NULL;    return stp->buf[stp->top-1];}/* *preorder of tree unrecursion *//* *For the node P: *Firstly, visiting the node P,and push the node P into stack *Secondly,Checking the node P's left child is NULL or not, * if this node is NULL,get the top of stack and push it. * At the end,put the current node P's right child become * current node P,and do the first step.If this node is not * NULL,put the left child become the current node P. *Thirdly,when the node P is NULL and the stack is NULL.It's * over. *//* * 对于任一结点P: *1)访问结点P,并将结点P入栈; *2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈 *  操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不 *  为空,则将P的左孩子置为当前的结点P; *3)直到P为NULL并且栈为空,则遍历结束。 */void preorder_unrecursion(Bit_tree bit){    stack_point stp;    Bit_tree bittree;    bittree = bit;    stp = init_stack(stp);    while(bittree || !stack_status(stp))    {        while(bittree)        {            printf("%c ",bittree->data);            push(stp,bittree);            bittree = bittree->lchild;        }        if(!stack_status(stp))        {            bittree = stack_top(stp);            pop(stp);            bittree = bittree ->rchild;        }    }}/* *Inorder of tree unrecursion *//* *For the node P: *First, if his left child not NULL,then put his left * child into the stack and put his left child become * current node. For the current node do same things * like the node P. *Second,if his left child is NULL, then get the top * of stack and pop the element.Printing the element.At * the end, put the node P's right child become the * current node P. *Third,when the node P is NULL.It's over. *//* *  对于任一结点P, *1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P, *  然后对当前结点P再进行相同的处理; *2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该 *  栈顶结点,然后将当前的P置为栈顶结点的右孩子; *3)直到P为NULL并且栈为空则遍历结束 */void Inorder_unrecursion(Bit_tree bt){    stack_point stp;    Bit_tree bittree;    stp = init_stack(stp);    bittree = bt;    while(bittree || !stack_status(stp))    {        while(bittree)        {            push(stp,bittree);            bittree = bittree->lchild;        }        if(!stack_status(stp))        {            bittree = stack_top(stp);            printf("%c ",bittree->data);            pop(stp);            bittree = bittree->rchild;        }    }}/* *Postorder of tree unrecursion *//* *I think visit the tree in postorder is very difficult. *First , when the node's leftchild is NULL,you can not *pop the node.Checking the right child NULL or not. If *the node's left child and right child is NULL.Print *the node.Second if the node's left child or right *child is not NULL.But the right or child has been *visited.You can print this node.If not these condition, *you should push the node into the stack. *//* *因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子, *则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩 *子和右孩子都已被访问过了,则同样可以直接访问该结点。 *若非上述两种情况,则将P的右孩子和左孩子依次入栈。 */void Postorder_unrecursion(Bit_tree bt){    stack_point stp;    Bit_tree bittree;    Bit_tree cur;    Bit_tree pre;    cur = bt;    pre=(tree *)malloc(sizeof(tree));    stp=init_stack(stp);    bittree = bt;    push(stp,bittree);    while(!stack_status(stp))    {        cur = stack_top(stp);        if((cur->lchild==NULL && cur->rchild==NULL) \           || (pre!=NULL && (pre == cur->lchild || pre == cur->rchild)))        {            printf("%c ",cur->data);            pop(stp);            pre = cur;        }        else        {            if(cur ->rchild !=NULL)                push(stp,cur->rchild);            if(cur ->lchild !=NULL)                push(stp,cur->lchild);        }    }}int main(){    Bit_tree bittree;    bittree = (tree *)malloc(sizeof(tree));    bittree = Create_bit_tree(bittree);    printf("Visitting the tree : \n");    preorder_bit_tree(bittree);    printf("\n");    inorder_bit_tree(bittree);    printf("\n");    beorder_bit_tree(bittree);    printf("\n");    printf("Unrecursion travel : \n");    preorder_unrecursion(bittree);    printf("\n");    Inorder_unrecursion(bittree);    printf("\n");    Postorder_unrecursion(bittree);    printf("\n");    return 0;}


测试用例:

ABC$$DE$G$$F$$$

输出结果:


对于遍历的思路参考了:

http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html

在这里把他分享给大家!对于思路方面的问题我习惯用英文注释,所以翻译了一下,但是限于英文水平有限,怕翻译的不准,只能把中文标上,对于这个翻译方面出的问题,望大家见谅。

0 0