数据结构实验43文档格式.docx
《数据结构实验43文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构实验43文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
/\
BC
/\/\
DEFG
六、分析与探讨
1.用按先序遍历输入的方法输入的字符画出二叉树,看图依次按先序、中序、后序的方法写出遍历后的序列与测试结果对比可知正确。
2.我在本实验中都是按递归的方法实现遍历,用栈操作也实现了非递归的遍历。
七、附录:
源代码
#include<
stdio.h>
#include<
stdlib.h>
//函数结果状态代码
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
#defineOVERFLOW-2//因为在math.h中已定义OVERFLOW的值为3,故去掉此行
#defineSTACK_INIT_SIZE100//存储空间初始分配量
#defineSTACKINCREMENT10//存储空间分配增量
typedefintStatus;
//Status是函数的类型,其值是函数结果状态代码,如OK等
typedefintBoolean;
//Boolean是布尔类型,其值是TRUE或FALSE
//二叉树结点
typedefstructBiTNode{
//数据
chardata;
//左右孩子指针
structBiTNode*lchild,*rchild;
}BiTNode,*BiTree;
typedefstructSqStack
{
BiTree*base;
//在栈构造之前和销毁之后,base的值为NULL
BiTree*top;
//栈顶指针*/
intstacksize;
//当前已分配的存储空间,以元素为单位
}SqStack;
//顺序栈
//按先序序列创建二叉树
intCreateBiTree(BiTree&
T){
//按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树
scanf("
%c"
&
data);
if(data=='
#'
){
T=NULL;
}
else{
T=(BiTree)malloc(sizeof(BiTNode));
//生成根结点
T->
data=data;
//构造左子树
CreateBiTree(T->
lchild);
//构造右子树
rchild);
return0;
}
//输出
voidVisit(BiTreeT){
if(T->
data!
='
printf("
%c"
T->
//先序遍历
voidPreOrder(BiTreeT){
if(T!
=NULL){
//访问根节点
Visit(T);
//访问左子结点
PreOrder(T->
//访问右子结点
//中序遍历
voidInOrder(BiTreeT){
=NULL){
//访问左子结点
InOrder(T->
//访问根节点
Visit(T);
//访问右子结点
}
}
//后序遍历
voidPostOrder(BiTreeT){
PostOrder(T->
//栈的基本操作
StatusInitStack(SqStack&
S)
{//构造一个空栈S
S.base=(BiTree*)malloc(STACK_INIT_SIZE*sizeof(BiTree));
if(!
S.base)
exit(-2);
/*存储分配失败*/
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
returnOK;
StatusStackEmpty(SqStackS)
{/*若栈S为空栈,则返回TRUE,否则返回FALSE*/
if(S.top==S.base)
returnTRUE;
else
returnFALSE;
StatusGetTop(SqStackS,BiTree&
e)
{/*若栈不空,则用e返回S的栈顶元素,并返回OK;
否则返回ERROR*/
if(S.top>
{
e=*(S.top-1);
returnOK;
returnERROR;
StatusPush(SqStack&
S,BiTreee)
{/*插入元素e为新的栈顶元素*/
if(S.top-S.base>
=S.stacksize)/*栈满,追加存储空间*/
S.base=(BiTree*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(BiTree));
if(!
exit(-2);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
*S.top++=e;
StatusPop(SqStack&
S,BiTree&
{/*若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;
e=*--S.top;
/*先序遍历(非递归)
思路:
访问T->
data后,将T入栈,遍历左子树;
遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
*/
voidPreOrder2(BiTreeT){
//p是遍历指针
BiTreep=T;
SqStackS;
InitStack(S);
//栈不空或者p不空时循环
while(p||!
StackEmpty(S)){
if(p!
//存入栈中
Push(S,p);
//访问根节点
printf("
p->
//遍历左子树
p=p->
lchild;
}
else{
//退栈
Pop(S,p);
//访问右子树
rchild;
}//while
/*中序遍历(非递归)
T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
先将T入栈,遍历左子树;
遍历完左子树返回时,栈顶元素应为T,出栈,访问T->
data,再中序遍历T的右子树。
voidInOrder2(BiTreeT){
//退栈,访问根节点
/*
//后序遍历(非递归)
typedefstructBiTNodePost{
BiTreebiTree;
chartag;
}BiTNodePost,*BiTreePost;
voidPostOrder2(BiTreeT){
stack<
BiTreePost>
stack;
BiTreePostBT;
while(p!
=NULL||!
stack.empty()){
//遍历左子树
while(p!
BT=(BiTreePost)malloc(sizeof(BiTNodePost));
BT->
biTree=p;
//访问过左子树
tag='
L'
;
stack.push(BT);
//左右子树访问完毕访问根节点
while(!
stack.empty()&
&
(stack.top())->
tag=='
R'
BT=stack.top();
stack.pop();
BT->
biTree->
//遍历右子树
//访问过右子树
p=BT->
biTree;
//层次遍历
voidLevelOrder(BiTreeT){
//队列
queue<
BiTree>
queue;
//根节点入队
queue.push(p);
//队列不空循环
while(!
queue.empty()){
//对头元素出队
p=queue.front();
//访问p指向的结点
//退出队列
queue.pop();
//左子树不空,将左子树入队
if(p->
lchild!
queue.push(p->
lc