二叉树仿真指针储存结构操作设计说明书.docx
《二叉树仿真指针储存结构操作设计说明书.docx》由会员分享,可在线阅读,更多相关《二叉树仿真指针储存结构操作设计说明书.docx(28页珍藏版)》请在冰豆网上搜索。
二叉树仿真指针储存结构操作设计说明书
数学与计算机学院
课程设计说明书
课程名称:
数据结构与算法课程设计
课程代码:
题目:
二叉树的仿真指针储存结构操作
年级/专业/班:
学生姓名:
学 号:
开始时间:
2011年12月08日
完成时间:
2011年12月20日
课程设计成绩:
学习态度及平时成绩(30)
技术水平与实际能力(20)
创新(5)
说明书(计算书、图纸、分析报告)撰写质量(45)
总分(100)
指导教师签名:
年月日
摘要
随着计算机的应用以惊人的速度普及,计算机的应用早已不局限于科学计算,而更多的应用在现实生活中。
数据的储存结构多种多样,其中树型结构是以分支关系定义的层次结构,是一种重要的非线性结构。
树型结构在客观世界中广泛存在,例如在计算机文件管理和信息组织方面用树型结构来表示,又如人类的家庭族谱以及各种社会组织机构也都可以用树型结构来表示。
而二叉树是一种有着重要用途的树型结构。
研究二叉树的基本概念、储存结构以及相关运算,对研究一般树的储存和运算有着重要意义。
本文研究二叉树的仿真指针储存结构的实现以及一般操作。
关键词:
储存结构;二叉树;仿真指针储存;一般操作。
引言
数据结构就是反映数据在内存中的存储方式以及对数据进行的一系列操作。
数据结构可以和生活实际相联系,用于解决生活中实际问题。
课程设计正是基于这个目的,通过课程设计,锻炼我们发现问题,解决问题的能力。
该次课程设计任务是实现有向图的邻接矩阵存储方式及其相关操作,采用VS2010编程环境。
1需求分析
1.1任务与分析
二叉树的仿真指针存储结构是用数组存储二叉树中的结点,数组中每个结点除数据元素域外,再增加仿真指针域用于仿真常规指针建立二叉树中结点之间的关系。
如右图所示,二叉树按仿真指针存储为:
数组下标
data
lchild
rchild
0
A
1
2
1
B
3
4
2
C
5
6
3
D
-1
-1
4
E
-1
-1
5
F
-1
-1
6
G
-1
-1
编写程序实现二叉树仿真指针存储结构,并实现如下操作:
1)输出该二叉树;
2)写出三种遍历算法,输出遍历序列;
3)二叉树的撤销操作
4)查找数据元素操作
5)求各结点度的操作
6)求出该二叉树的深度
7)判断该二叉树是否是完全二叉树?
1.2测试数据
1.2.1二叉树1
数组下标
data
lchild
rchild
0
A
1
2
1
B
3
4
2
C
5
-1
3
D
-1
-1
4
E
-1
-1
5
F
-1
-1
1.2.2二叉树2
数组下标
data
lchild
rchild
0
A
1
2
1
B
3
4
2
C
5
-1
3
D
-1
-1
4
E
6
-1
5
F
-1
-1
6
G
-1
-1
1.2.3二叉树3
数组下标
data
lchild
rchild
0
A
-1
-1
2概要设计
2.1ADT描述
ADTBinaryTree{
数据对象:
D={具有相同特性的数据元素的有限集合;}
数据关系:
R={顺序储存}
基本操作:
初始化一棵空树;
建立一颗二叉树;
输出一颗二叉树;
二叉树的先序遍历;
二叉树的中序遍历;
二叉树的后序遍历;
二叉树中数据元素的查找;
求二叉树深度;
求二叉树各结点度;
判断二叉树是否是完全二叉树;
销毁二叉树;
等等;
}ADTBinaryTree;
2.2程序模块结构
2.3各功能模块
BiTree();//构造函数
~BiTree(){};//析构函数
voidMenu();//菜单函数
voidCreat();//建立二叉树
voidDisplay();//输出二叉树
voidPreOrder();//先序遍历
voidInOrder();//中序遍历
voidPostOrder();//后序遍历
voidDestroy()//撤销二叉树
voidSearch();//查找数据元素
voidPreDegree();//求各结点度
intPreDepth(NodeTypebt);//求二叉树的深度
voidPreDepth_BT();//调用PreDepth(NodeTypebt)
intmax(intx,inty);//比较函数
voidIsFull_BT();//调用Is_Full(NodeTypem)
boolIs_Full(NodeTypem);//7)判断二叉树是否是完全二叉树
3 详细设计
3.1结构体定义
structNodeType
{
ElemTypedata;//存放结点值
intLChild,RChild;//存放左、右孩子的数组元素的下标
};
3.2栈模板定义
#include"stdafx.h"
templateclassSqStack
{
private:
Type*stackspace;
intmaxsize;
inttop;
public:
SqStack(intm=30);
intIsEmpty(){returntop==-1;}
intIsFull(){returntop==maxsize-1;}
voidPush(Typep);
TypePop();
TypeGetTop();
};
templateSqStack:
:
SqStack(intm)
{
top=-1;maxsize=m;stackspace=newType[maxsize];
}
templatevoidSqStack:
:
Push(Typep)
{
if(!
IsFull())
{top++;stackspace[top]=p;}
}
templateTypeSqStack:
:
Pop()
{
Typep;
if(!
IsEmpty())
{p=stackspace[top];top--;}
returnp;
}
templateTypeSqStack:
:
GetTop()
{
if(!
IsEmpty())returnstackspace[top];
}
3.3类定义
classBiTree
{
private:
intlength;
NodeType*BT;
public:
BiTree();
~BiTree(){};
voidMenu();
voidCreat();//建立二叉树
voidDisplay();//1)输出二叉树
voidPreOrder();//2)先序遍历
voidInOrder();//2)中序遍历
voidPostOrder();//2)后序遍历
voidDestroy()//3)撤销二叉树
voidSearch();//4)查找数据元素
voidPreDegree();//5)求各结点度
intPreDepth(NodeTypebt);//6)求二叉树的深度
voidPreDepth_BT();
intmax(intx,inty);
voidIsFull_BT();
boolIs_Full(NodeTypem);//7)判断二叉树是否是完全二叉树
};
3.4初始化
BiTree:
:
BiTree()
{
BT=newNodeType[MaxSize];length=0;
for(inti=0;i{BT[i].data="";BT[i].LChild=-1;BT[i].RChild=-1;}
}
3.5创建二叉树操作
voidBiTree:
:
Creat()
{
intL;
cout<<"输入二叉树结点总个数:
";
cin>>L;length=L;
if(length!
=0)
{
cout<<"按层序遍历输入二叉树数据(数据,左孩子下标,右孩子下标):
\n";
for(inti=0;i{
cin>>BT[i].data;cin>>BT[i].LChild;cin>>BT[i].RChild;
}
}
}
3.6输出二叉树操作
voidBiTree:
:
Display()//1)输出二叉树
{
if(length==0)
cout<<"二叉树为空!
!
!
\n";
else
{
cout<<"按层序遍历输出二叉树数据:
\n";
cout<<"数组下标数据(data)左孩子(LChild)右孩子(RChild)\n";
for(inti=0;i{cout<
}
}
3.7先序遍历操作
voidBiTree:
:
PreOrder()//2)先序遍历输出
{
if(length==0)
cout<<"二叉树为空!
!
!
\n";
else
{
cout<<"按先序遍历输出二叉树数据:
\n";
cout<<"数组下标数据(data)左孩子(LChild)右孩子(RChild)\n";
NodeTypem;m=BT[0];
inti=0,Bool=1;
SqStacks;
SqStackt;
while(Bool)
{
while(i!
=-1)
{
cout<
s.Push(m);t.Push(i);
i=BT[i].LChild;
if(i==-1)break;
elsem=BT[i];
}
if(s.IsEmpty()&&t.IsEmpty())Bool=0;
else
{
i=t.Pop();m=s.Pop();
while(m.RChild==-1&&!
s.IsEmpty()&&!
t.IsEmpty())
{i=t.Pop();m=s.Pop();}
i=BT[i].RChild;
if(i==-1);
elsem=BT[i];
}
}
}
}
3.8中序遍历操作
voidBiTree:
:
InOrder()//2)中序遍历输出
{
if(length==0)
cout<<"二叉树为空!
!
!
\n";
else
{
cout<<"按中序遍历输出二叉树数据:
\n";
cout<<"数组下标数据(data)左孩子(LChild)右孩子(RChild)\n";
NodeTypem;m=BT[0];
inti=0,Bool=1;
SqStacks;
SqStackt;
while(Bool)
{
while(i!
=-1)
{
s.Push(m);t.Push(i);
i=BT[i].LChild;
if(i==-1)break;
elsem=BT[i];
}
if(s.IsEmpty()&&t.IsEmpty())Bool=0;
else
{
i=t.Pop();m=s.Pop();
while(m.RChild==-1&&!
s.IsEmpty()&&!
t.IsEmpty())
{
cout<
i=t.Pop();m=s.Pop();
}
cout<
i=BT[i].RChild;
if(i==-1);
elsem=BT[i];
}
}
}
}
3.9后序遍历操作
voidBiTree:
:
PostOrder()//2)后序遍历输出
{
if(length==0)
cout<<"二叉树为空!
!
!
\n";
else
{
cout<<"按后序遍历输出二叉树数据:
\n";
cout<<"数组下标数据(data)左孩子(LChild)右孩子(RChild)\n";
NodeTypem;m=BT[0];
inti=0,Bool=1,printed[MaxSize];
for(intj=0;jSqStacks;
SqStackt,j;
while(Bool)
{
while(i!
=-1)
{
s.Push(m);t.Push(i);j.Push
(1);
i=BT[i].LChild;
if(i==-1)break;
elsem=BT[i];
}
if(s.IsEmpty()&&t.IsEmpty())Bool=0;
else
{
if(j.GetTop()==1)
{
j.Pop();j.Push
(2);i=t.GetTop();m=s.GetTop();
i=BT[i].RChild;
if(i==-1);
elsem=BT[i];
}
else
{
i=t.Pop();m=s.Pop();j.Pop();
cout<
printed[i]=1;
i=BT[i].RChild;
if(i==-1);
else
{
if(printed[i]==1)i=-1;
elsem=BT[i];
}
}
}
}
}
}
3.10撤销二叉树操作
voidDestroy()//3)撤销二叉树
{length=0;delete[]BT;cout<<"撤销二叉树成功!
!
!
\n";}
3.11查找操作
voidBiTree:
:
Search()//4)查找数据元素
{
if(length==0)
cout<<"二叉树为空!
!
!
\n";
else
{
ElemTypeelem;inti;
cout<<"输入需查找的结点数据(结点值):
";
cin>>elem;
for(i=0;i{
if(elem==BT[i].data)
{
cout<<"查找的结点如下:
\n";
cout<<"数组下标:
"<
"<cout<<"左孩子下标:
"<"<break;
}
}
if(i>=MaxSize)
{cout<<"查找的结点不存在!
!
!
\n";}
}
}
3.12求各节点度操作
voidBiTree:
:
PreDegree()//5)求各结点度
{
if(length==0)
cout<<"二叉树为空!
!
!
\n";
else
{
intDG;
for(inti=0;i{
DG=0;
if(BT[i].LChild!
=-1)DG++;
if(BT[i].RChild!
=-1)DG++;
cout<<"数组下标:
"<
"<"<}
}
}
3.13求二叉树深度操作
voidBiTree:
:
PreDepth_BT()
{
if(length==0)
cout<<"二叉树为空,树的深度为!
!
!
\n";
else
{
NodeTypebt=BT[0];
cout<<"树的深度为:
"<}
}
intBiTree:
:
PreDepth(NodeTypebt)//6)求二叉树的深度
{
intLDep,RDep;
if(bt.LChild==-1&&bt.RChild==-1)return1;
else
{
if(bt.LChild==-1)LDep=0;
elseLDep=PreDepth(BT[bt.LChild]);
if(bt.RChild==-1)RDep=0;
elseRDep=PreDepth(BT[bt.RChild]);
return1+max(LDep,RDep);
}
}
intBiTree:
:
max(intx,inty)
{
return(x>=y?
x:
y);
}
3.14判断操作
voidBiTree:
:
IsFull_BT()//7)判断二叉树是否是完全二叉树
{
if(length==0)
cout<<"二叉树为空!
!
!
\n";
else
{
NodeTypebt=BT[0];
if(Is_Full(bt))//调用Is_FullBT(bt)函数判断是否是完全二叉树,是则返回真,否则返回假
cout<<"该二叉树是完全二叉树!
!
!
\n";
else
cout<<"该二叉树不是完全二叉树!
!
!
\n";
}
}
boolBiTree:
:
Is_Full(NodeTypebt)
{
intnum1=1,num2=2,j=0;
if(bt.LChild==-1&&bt.RChild==-1)//判断二叉树是否只有根节点,若只有根节点,则是完全二叉树,返回真。
returntrue;
else
{
for(inti=1;i{num1*=2;num2*=2;}
if(num1-1>=length||num2-12^(PreDepth(bt)-1)-1,<=(2^PreDepth(bt))-1,若不是,返回假
returnfalse;
else
{
while(2*j<=length-1)//2*j<=length-1时,节点j有下标为*j+1的左孩子,否则没有。
若有左孩子但下标不为*j+1,则返回假
{
if(BT[j].LChild!
=-1&&BT[j].LChild!
=2*j+1)
returnfalse;
elsej++;
}
j=0;
while(2*j+1<=length-1)//2*j<=length-1时,节点j有且只有下标为*j+1+1的右孩子,否则没有。
若有右孩子但下标不为*j+1,则返回假
{
if(BT[j].RChild!
=-1&&BT[j].RChild!
=2*j+1+1)
returnfalse;
elsej++;
}
}
returntrue;
}
}
3.15菜单函数
voidBiTree:
:
Menu()
{
intchoice;
cout<<"*****二叉树的仿真指针存储结构操作*****\n";
cout<<"*1.建立二叉树*\n";
cout<<"*2.输出二叉树*\n";
cout<<"*3.先序遍历二叉树*\n";
cout<<"*4.中序遍历二叉树*\n";
cout<<"*5.后序遍历二叉树*\n";
cout<<"*6.撤销二叉树*\n";
cout<<"*7.查找数据元素*\n";
cout<<"*8.求各结点度*\n";
cout<<"*9.求二叉树的深度*\n";
cout<<"*10.判断二叉树是否是完全二叉树*\n";
cout<<"*0.退出*\n";
cout<<"************谢谢使用!
!
!
************\n";
cout<<"请输入选择:
";
cin>>choice;
switch(choice)
{
case1:
{Creat();Menu();cout<case2:
{Display();cout<case3:
{PreOrder();cout<case4:
{InOrder();cout<case5:
{PostOrder();cout<ca