4.5.2基于栈的递归消除

// DataStructTest.cpp : Defines the entry point for the console application.

//说明:书中使用的为顺序栈结构,但栈的使用是在遍历时模拟的,为了重用以前的代码,我使用了以前实现的顺序栈结构

#include 
"stdafx.h"
#include 
<iostream.h>
#include 
<malloc.h>

//--------------------------------------------声明类型----------------------------------------
typedef struct btnode * bitreptr;
//二叉树结点类型
struct btnode
{
    
char data;                    //数据
    bitreptr lchild;            //左节点指针
    bitreptr rchild;            //右节点指针
}
;

int const sqstack_maxsize=100;
struct sqstack
{
    bitreptr data[sqstack_maxsize];
    
int top;
}
;

//--------------------------------------------栈相关-------------------------------------------

//初始化栈
void InitStack(sqstack * sq)
{
    sq
->top=0;
}

//入栈
int Push(sqstack * sq,bitreptr value)
{
    
if (sq->top<sqstack_maxsize)
    
{
        sq
->top++;
        sq
->data[sq->top-1]=value;
        
return 1;
    }

    
else
    
{
        
return 0;
    }

}

//出栈
int Pop(sqstack & sq,bitreptr & value)
{
    
if (sq.top==0)
    
{
        
return 0;
    }

    value
=sq.data[sq.top-1];
    sq.top
--;
    
return 1;
}

//判断空栈
int EmptyStack(sqstack & sq)
{
    
if (sq.top==0)
        
return 1;
    
else
        
return 0;
}

//--------------------------------------------树相关-------------------------------------------

//建立一个树,与书中P84中的是一样的,函数返回一个树的头指针
bitreptr CreateTree()            
{
    bitreptr A,B,C,D,E,F;
    bitreptr nodes[
6];
    
for(int i=0;i<6;i++)
    
{
        nodes[i]
=(bitreptr)malloc(sizeof(btnode));
        nodes[i]
->lchild=NULL;
        nodes[i]
->rchild=NULL;
    }

    A
=nodes[0];
    B
=nodes[1];
    C
=nodes[2];
    D
=nodes[3];
    E
=nodes[4];
    F
=nodes[5];

    A
->data='A';
    A
->lchild=B;
    A
->rchild=E;

    B
->data='B';
    B
->lchild=C;
    B
->rchild=D;

    C
->data='C';

    D
->data='D';

    E
->data='E';
    E
->rchild=F;

    F
->data='F';

    
return A;
}


void visit(const bitreptr node)
{
    cout
<<node->data<<endl;;
}


//-------------------------------------------使用栈消除递归遍历二叉树----------------------------------

void PreOrder(bitreptr root)
{
    sqstack stack;
    
//初始化栈
    InitStack(&stack);
    
//将根结点入栈
    Push(&stack,root);
    
//遍历
    while(!EmptyStack(stack))
    
{
        bitreptr node
=NULL;
        Pop(stack,node);
        
while(node!=NULL)
        
{
            visit(node);
            
//书上的做法是没有判断直接入栈,我认为判断一下比较好.
            
//但结果都是正确的,采用不判断的做法:因为入栈的的值为NULL,则在判断while(node!=NULL)时会返回假,直接进行下个结点的出栈
            
//采用判断的做法,则入栈的肯定都是有结点,则在第一次while(node!=NULL)肯定都为真.
            
//当然了,两种做法都可以.我认为我的做法会减少歧义,但是做法和书中的不一样.
            if (node->rchild!=NULL)
            
{
                Push(
&stack,node->rchild);
            }

            node
=node->lchild;
        }

    }

}


int main(int argc, char* argv[])
{
    bitreptr root
=CreateTree();
    PreOrder(root);
    
//消毁树释放内存,因减少代码量所以省略
    return 0;
}

posted @ 2007-07-12 16:19  吴东雷  阅读(553)  评论(0编辑  收藏  举报