浙大城院数据结构report10.docx
《浙大城院数据结构report10.docx》由会员分享,可在线阅读,更多相关《浙大城院数据结构report10.docx(17页珍藏版)》请在冰豆网上搜索。
浙大城院数据结构report10
浙江大学城市学院实验报告
课程名称数据结构基础
实验项目名称实验十二叉树的基本操作
学生姓名专业班级学号
实验成绩指导老师(签名)日期
三.函数的功能说明及算法思路
树的基本函数
voidInitBTree(BTreeNode*&BT);//初始化二叉树BT
intEmptyBTree(BTreeNode*BT);//检查二叉树BT是否为空,空返回1,否则返回0
intDepthBTree(BTreeNode*BT);//求二叉树BT的深度并返回该值
intFindBTree(BTreeNode*BT,ElemTypex);//查找二叉树BT中值为x的结点,若查找成功返回1,否则返回0
voidPreOrder(BTreeNode*BT);//先序遍历二叉树BT
voidInOrder(BTreeNode*BT);//中序遍历二叉树BT
voidPostOrder(BTreeNode*BT);//后序遍历二叉树BT
voidPrintBTree(BTreeNode*BT);//输出二叉树BT
voidClearBTree(BTreeNode*&BT);//清除二叉树BT
voidCreateBTree(BTreeNode*&BT,char*a)//根据字符串a所给出的广义表表示的二叉树建立二叉链表存储结构
树的附加函数
voidLevelOrder(BTreeNode*BT){//按层次遍历二叉树BT
定义并且初始化队列q
if(树不空){
根结点入队;
while(队列不空){
BT=出队的元素
访问该结点
if(BT的左孩子不空)
BT的左孩纸入队列;
if(BT的右孩子不空)
BT的右孩纸入队列;
}
}
}
intGet_Sub_Depth(BTreeNode*T,ElemTypex)//求二叉树中以元素值为x的结点为根的子树的深度
{
if(BT不是空){
if(BT->data==x)
返回BT的深度;
Else
返回Get_Sub_Depth(BT的左孩纸,x)和Get_Sub_Depth(BT-的右孩纸,x)中的较大值
}
Else
返回0;}
}
顺序栈的操作(voidCreateBTree(BTreeNode*&BT,char*a)//根据字符串a所给出的广义表表示的二叉树建立二叉链表存储结构中要用到顺序栈的结构)
voidInitStack(Stack&S)//构造一个空栈S
intEmptyStack(StackS)//若栈S为空栈返回1,否则返回0
voidPush(Stack&S,BTreeNode*item)//元素item进栈
BTreeNode*Pop(Stack&S)//栈S的栈顶元素出栈并返回
BTreeNode*Peek(StackS)//取栈S的当前栈顶元素并返回
循环队列的操作(voidLevelOrder(BTreeNode*BT)按层次遍历二叉树B函数中要用到队列存储树中元素)
voidInitQueue(Queue&Q)//初始化循环队列Q
intEmptyQueue(QueueQ)//判断队列是否为空,空返回1,否则返回0
voidEnQueue(Queue&Q,BTreeNode*item)//进队列
BTreeNode*OutQueue(Queue&Q)//出队列
四.实验结果与分析
(包括运行结果截图、结果分析等)
先定义了一个二叉树,因为是空,所以输出”改二叉树为空”的信息
之后输入广义表再定义为二叉树,再对二叉树进行一系列操作
五.心得体会
(记录实验感受、上机过程中遇到的困难及解决办法、遗留的问题、意见和建议等。
)
出错点:
在binary_tree.h头文件中,对顺序栈以及队列的定义在树的定义之后,导致在编译中,先编译树的函数,调用顺序栈以及队列出错
改正:
将顺序栈以及队列的函数定义在树函数之前
【附录----源程序】
binary_tree.h
/*————————顺序栈的操作—————————*/
structStack
{
BTreeNode**stack;//存栈元素
inttop;/栈顶指示器
intMaxSize;/栈的最大长度
};
voidInitStack(Stack&S)//构造一个空栈S
{
S.MaxSize=10;
S.stack=(BTreeNode**)malloc(S.MaxSize*sizeof(BTreeNode*));
if(!
S.stack){
cout<<"分配空间失败"<(1);
}
S.top=-1;
}
intEmptyStack(StackS)//若栈S为空栈返回1,否则返回0
{
returnS.top==-1;
}
voidPush(Stack&S,BTreeNode*item)//元素item进栈
{
if(S.top==S.MaxSize-1)
{
S.stack=(BTreeNode**)realloc(S.stack,S.MaxSize*sizeof(BTreeNode*)*2);
S.MaxSize*=2;
}
S.top++;
S.stack[S.top]=item;
}
BTreeNode*Pop(Stack&S)//栈S的栈顶元素出栈并返回
{
BTreeNode*temp;
if(S.top==-1)
{
cout<<"顺序链为空"<exit
(1);
}
S.top--;
temp=S.stack[S.top+1];
returntemp;
}
BTreeNode*Peek(StackS)//取栈S的当前栈顶元素并返回
{
returnS.stack[S.top];
}
/*——————————循环队列的操作—————————————*/
structQueue{
BTreeNode**queue;
intMaxSize;//队列最大存储数
intfront;//头指针,若队列不空,指向队列头元素的前一个位置
intrear;//尾指针,若队列不空,指向队列尾元素
};
voidInitQueue(Queue&Q)//初始化循环队列Q
{
Q.MaxSize=20;
Q.queue=(BTreeNode**)malloc(Q.MaxSize*sizeof(BTreeNode*));
Q.rear=Q.front=0;
}
intEmptyQueue(QueueQ)//判断队列是否为空,空返回1,否则返回0
{
returnQ.rear==Q.front;
}
voidEnQueue(Queue&Q,BTreeNode*item)//进队列
{
if((Q.rear+1)%Q.MaxSize==Q.front)//空间不足,扩大2倍
{
intk=sizeof(BTreeNode*);
Q.queue=(BTreeNode**)realloc(Q.queue,2*Q.MaxSize*k);
if(Q.rear!
=Q.MaxSize-1)
{//移动队列内容,必须要做
for(inti=0;i<=Q.rear;i++)
Q.queue[i+Q.MaxSize]=Q.queue[i];
Q.rear=Q.rear+Q.MaxSize;
}
Q.MaxSize=2*Q.MaxSize;//修改队列最大空间
}
Q.rear=(Q.rear+1)%Q.MaxSize;//元素入队
Q.queue[Q.rear]=item;
}
BTreeNode*OutQueue(Queue&Q)
{
if(Q.rear==Q.front)
{
printf("队列已空无数据元素出队列!
\n");
exit
(1);
}
//先修改front位置,后取走元素
Q.front=(Q.front+1)%Q.MaxSize;
returnQ.queue[Q.front];
}
/*——————————树的操作————-———————*/
voidInitBTree(BTreeNode*&BT)//初始化二叉树BT
{
BT=NULL;
}
voidCreateBTree(BTreeNode*&BT,char*a)//根据字符串a所给出的广义表表示的二叉树建立二叉链表存储结构
{
Stacks;//堆栈
BTreeNode*p,*t;//p指向新申请的结点,t指向栈顶结点
intk,i=0;//k=1表示将处理左子树,k=2表示处理右子树
BT=NULL;
InitStack(s);//初始化堆栈
while(a[i])//一个个读入字符进行处理直到读到'\0'为止
{
switch(a[i])
{
case'':
break;
case'(':
Push(s,p);k=1;break;
case')':
Pop(s);break;
case',':
k=2;break;
default:
//只可能是字符,即结点值
p=(BTreeNode*)malloc(sizeof(BTreeNode));
p->data=a[i];
p->lchild=p->rchild=NULL;
if(BT==NULL)
BT=p;
else
{
t=Peek(s);
if(k==1)
t->lchild=p;
else
t->rchild=p;
}
}
i++;
}
}
intEmptyBTree(BTreeNode*BT)//检查二叉树BT是否为空,空返回1,否则返回0
{
returnBT==NULL;
}
intDepthBTree(BTreeNode*BT)//求二叉树BT的深度并返回该值
{
if(BT==NULL)//空树深度为0
return0;
else
{
intdep1=DepthBTree(BT->lchild);//先求根结点左子树的深度
intdep2=DepthBTree(BT->rchild);//再求根结点右子树的深度
if(dep1>dep2)//返回最大值,并加上根结点这一层
returndep1+1;
else
returndep2+1;
}
}
intFindBTree(BTreeNode*BT,ElemTypex)//查找二叉树BT中值为x的结点,若查找成功返回1,否则返回0
{
if(BT==NULL)
return0;
else
{
if(BT->data==x)
return1;
else
{
if(FindBTree(BT->lchild,x))return1;
if(FindBTree(BT->rchild,x))return1;
return0;
}
}
}
voidPreOrder(BTreeNode*BT)//先序遍历二叉树BT
{
if(BT)
{
cout<data<<'';//访问根结点
PreOrder(BT->lchild);//先序遍历左子树
PreOrder(BT->rchild);//先序遍历右子树
}
}
voidInOrder(BTreeNode*BT)//中序遍历二叉树BT
{
if(BT)
{
InOrder(BT->lchild);//中序遍历左子树
cout<data<<'';//访问根结点
InOrder(BT->rchild);//中序遍历右子树
}
}
voidPostOrder(BTreeNode*BT)//后序遍历二叉树BT
{
if(BT)
{
PostOrder(BT->lchild);//后序遍历左子树
PostOrder(BT->rchild);//后序遍历右子树
cout<data<<'';//访问根结点
}
}
voidPrintBTree(BTreeNode*BT)//输出二叉树BT
{
if(BT)//树非空
{
cout<data;//输出根结点
if(BT->lchild!
=NULL||BT->rchild!
=NULL)//若非叶子结点,则递归调用输出左右子树
{
cout<<'(';
PrintBTree(BT->lchild);
if(BT->rchild!
=NULL)
{
cout<<',';
PrintBTree(BT->rchild);
}
cout<<')';
}
}
}
voidClearBTree(BTreeNode*&BT)//清除二叉树BT
{
if(BT){
ClearBTree(BT->lchild);//先递归删除左子树
ClearBTree(BT->rchild);//再递归删除右子树
free(BT);//最后释放根结点
BT=NULL;//根指针为空
}
}
/*———————附加的操作———————*/
//按层次遍历二叉树BT
voidLevelOrder(BTreeNode*BT)//按层次遍历:
利用队列,每次访问队头结点,一旦访问某结点,它的左右孩子入队列,该结点出队列
{
Queueq;//定义一个队列
InitQueue(q);//初始化队列
if(BT)//树不空
{
EnQueue(q,BT);//根结点入队
while(!
EmptyQueue(q))//队列不空
{
BT=OutQueue(q);//出队
cout<data<<'';//访问该结点
if(BT->lchild!
=NULL)
EnQueue(q,BT->lchild);
if(BT->rchild!
=NULL)
EnQueue(q,BT->rchild);
}
}
}
intDepthx(BTreeNode*BT,ElemTypex){
intm,n;
if(BT){
if(BT->data==x)
returnDepthBTree(BT);
else
{
m=Depthx(BT->lchild,x);
n=Depthx(BT->rchild,x);
returnm>n?
m:
n;
}
}
else{
return0;
}
}
Test4_1.cpp
#include
#include
#include
typedefcharElemType;
structBTreeNode{
ElemTypedata;
BTreeNode*lchild;
BTreeNode*rchild;};
#include"binary_tree.h"
voidmain(){
BTreeNode*T1,*T2,*T3;
charch[80],x;//x用于存放查找的数据
InitBTree(T1);//初始化二叉树
cout<<"基本功能测试"<EmptyBTree(T1)?
cout<<"该二叉树为空"<cout<<"该二叉树非空"<printf("请输入广义表:
");
gets(ch);//将广义表保存在ch字符串中
CreateBTree(T1,ch);//建立二叉树
EmptyBTree(T1)?
cout<<"该二叉树为空"<cout<<"该二叉树非空"<cout<<"该树的深度为"<printf("输入要查找的元素1:
");
cin>>x;
if(FindBTree(T1,x))
{
cout<<"该元素在二叉树中"<cout<<"且二叉树中以该元素结点为根的子树的深度为"}
else
cout<<"该元素不在二叉树中"<cout<<"先序序列:
";//先序序列
PreOrder(T1);cout<cout<<"中序序列:
";//中序序列
InOrder(T1);cout<cout<<"后序序列:
";//后序序列
PostOrder(T1);
cout<cout<<"层序序列:
";//层序序列
LevelOrder(T1);
cout<cout<<"输出二叉树:
";//输出二叉树
PrintBTree(T1);
cout<cout<ClearBTree(*&T1);//清除二叉树
}