// DataStructTest.cpp : Defines the entry point for the console application.
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//说明:书中使用的为顺序栈结构,但栈的使用是在遍历时模拟的,为了重用以前的代码,我使用了以前实现的顺序栈结构
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
#include "stdafx.h"
#include <iostream.h>
#include <malloc.h>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//--------------------------------------------声明类型----------------------------------------
typedef struct btnode * bitreptr;
//二叉树结点类型
struct btnode
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
char data; //数据
bitreptr lchild; //左节点指针
bitreptr rchild; //右节点指针
};
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
int const sqstack_maxsize=100;
struct sqstack
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
bitreptr data[sqstack_maxsize];
int top;
};
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//--------------------------------------------栈相关-------------------------------------------
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//初始化栈
void InitStack(sqstack * sq)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
sq->top=0;
}
//入栈
int Push(sqstack * sq,bitreptr value)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
if (sq->top<sqstack_maxsize)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
sq->top++;
sq->data[sq->top-1]=value;
return 1;
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return 0;
}
}
//出栈
int Pop(sqstack & sq,bitreptr & value)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
if (sq.top==0)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return 0;
}
value=sq.data[sq.top-1];
sq.top--;
return 1;
}
//判断空栈
int EmptyStack(sqstack & sq)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
if (sq.top==0)
return 1;
else
return 0;
}
//--------------------------------------------树相关-------------------------------------------
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//建立一个树,与书中P84中的是一样的,函数返回一个树的头指针
bitreptr CreateTree()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
bitreptr A,B,C,D,E,F;
bitreptr nodes[6];
for(int i=0;i<6;i++)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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];
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
A->data='A';
A->lchild=B;
A->rchild=E;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
B->data='B';
B->lchild=C;
B->rchild=D;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
C->data='C';
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
D->data='D';
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
E->data='E';
E->rchild=F;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
F->data='F';
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return A;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
void visit(const bitreptr node)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
cout<<node->data<<endl;;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//-------------------------------------------使用栈消除递归遍历二叉树----------------------------------
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
void PreOrder(bitreptr root)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
sqstack stack;
//初始化栈
InitStack(&stack);
//将根结点入栈
Push(&stack,root);
//遍历
while(!EmptyStack(stack))
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
bitreptr node=NULL;
Pop(stack,node);
while(node!=NULL)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
visit(node);
//书上的做法是没有判断直接入栈,我认为判断一下比较好.
//但结果都是正确的,采用不判断的做法:因为入栈的的值为NULL,则在判断while(node!=NULL)时会返回假,直接进行下个结点的出栈
//采用判断的做法,则入栈的肯定都是有结点,则在第一次while(node!=NULL)肯定都为真.
//当然了,两种做法都可以.我认为我的做法会减少歧义,但是做法和书中的不一样.
if (node->rchild!=NULL)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Push(&stack,node->rchild);
}
node=node->lchild;
}
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
int main(int argc, char* argv[])
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
bitreptr root=CreateTree();
PreOrder(root);
//消毁树释放内存,因减少代码量所以省略
return 0;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
一点说明:为什么在标题中要嵌入英文?原因是为了能够让国外的网友能查询到这篇文章。平常在Google上查资料的时候,经常参考国外网友的博客,帮助我解决了很多问题,所以我也想让他们能够参考我写的内容。当然文中我不可能全部译为英文,所以我尽量把代码粘全,靠代码说话吧。