二叉树抽象数据类型数据结构实验报告.docx
《二叉树抽象数据类型数据结构实验报告.docx》由会员分享,可在线阅读,更多相关《二叉树抽象数据类型数据结构实验报告.docx(29页珍藏版)》请在冰豆网上搜索。
![二叉树抽象数据类型数据结构实验报告.docx](https://file1.bdocx.com/fileroot1/2022-11/27/999b665d-8ea2-44d6-8fff-737e663046b3/999b665d-8ea2-44d6-8fff-737e663046b31.gif)
二叉树抽象数据类型数据结构实验报告
二叉树抽象数据类型数据结构实验报告
————————————————————————————————作者:
————————————————————————————————日期:
ﻩ
数据结构实验报告
题目:
二叉树抽象数据类型的实现
学院 ***学院
专 业 *********
年级班别 ***********
学 号 ***********
学生姓名*************
指导教师
成 绩____________________
2012年6月
报告:
内容:
ﻩ□详细 □完整ﻩ□不完整
设计方案:
□非常合理 ﻩ□合理ﻩﻩ□较差
实现:
□全部实现 □部分实现ﻩ□未实现
文档格式:
ﻩ□规范□基本规范 ﻩ□不规范
答辩:
□理解题目透彻,问题回答流利
□理解题目较透彻,回答问题基本正确
□部分理解题目,部分问题回答正确
□未能完全理解题目,答辩情况较差
总评成绩:
□优□良 □中 □及格 □不及格
一.实验概要
二叉树抽象数据类型的实现
二.实验目的
1.了解二叉树的定义以及各项基本操作。
2.实现二叉树存储、遍历及其他基本功能
三.实验仪器设备和材料
Visual studio2010
四.实验的内容
1.二叉树类型定义以及各基本操作的简要描述;
ADTBinaryTree {
数据对象D:
D是具有相同特性的数据元素的集合.
数据关系R:
若D=∅,则R=,称BinaryTree为空二叉树;
若D≠,则R={H},H是如下二元关系:
(1)在D中存在惟一的称为根的数据元素root,它在关系H下无前驱;
(2)若D-{root}≠∅,则存在D-{root}={D1,Dr},且D1∩Dr=∅;
(3)若D1≠∅,则D1中存在惟一的元素x1,∈H,且存在Dr上的关系Hr∈H;H={,,H1,Hr};
(4)(D1,{H1})是一棵符合本定义的二叉树,称为根的左子树,是一棵符合本定义的二叉树,称为根的右子树。
基本操作P:
InitBiTree(&T);
操作结果:
构造空二叉树T。
DestroyBiTree(&T);
初始条件:
二叉树T存在。
操作结果:
销毁二叉树T。
CreateBiTree(&T,definition);
初始条件:
definition给出二叉树T的定义。
操作结果:
按definition构造二叉树T。
ClearBiTree(&T);
初始条件:
二叉树T存在。
操作结果:
将二叉树T清为空树。
BiTreeEmpty(T);
初始条件:
二叉树T存在。
操作结果:
若T为空二叉树,则返回TURE,否则FALSE。
BiTreeDepth(T);
初始条件:
二叉树T存在。
操作结果:
返回T的深度。
Root(T);
初始条件:
二叉树T存在。
操作结果:
返回T的根。
Value(T,e);
初始条件:
二叉树T存在,e是T中的某个结点。
操作结果:
返回e的值。
Assign(T,&e,value);
初始条件:
二叉树T存在,e是T中的某个结点。
操作结果:
结点e赋值为value。
Parent(T,e);
初始条件:
二叉树T存在,e是T中的某个结点。
操作结果:
若e是T的非跟结点,则返回它的双亲,否则返回“空”。
LeftChild(T,e);
初始条件:
二叉树T存在,e是T中的某个结点。
操作结果:
返回e的左孩子。
若e无左孩子,则返回“空”。
RightChild(T,e);
初始条件:
二叉树T存在,e是T中的某个结点。
操作结果:
返回e的右孩子。
若e无右孩子,则返回“空”。
LeftSibling(T,e);
初始条件:
二叉树T存在,e是T中的某个结点。
操作结果:
返回e的左兄弟。
若e无左孩子或无左兄弟,则返回“空”。
RightSibling(T,e);
初始条件:
二叉树T存在,e是T中的某个结点。
操作结果:
返回e的右兄弟。
若e无右孩子或无右兄弟,则返回“空”。
}ADTBinaryTree
2.所选择的存储结构描述及在此存储结构上各基本操作的实现;
3.源代码
主文件:
main.ccp:
#include"base.h"ﻩﻩﻩ//公用头文件、公共常量及公共函数等
#include"bitree.h"ﻩﻩﻩ// 二叉树二叉链表基本操作
voidMenu();ﻩﻩﻩﻩ// 菜单函数
voidProduce(char*str);ﻩ//随机产生二叉树先序序列函数
intﻩﻩmain()ﻩﻩﻩﻩ// 主函数
{
BiTreeﻩT,bt,insert_bt;
ﻩcharcmd,str[MAXSIZE],elem;
intloc,temp;
ﻩInitBiTree(T);ﻩﻩ//初始化二叉链表二叉树
ﻩMenu();ﻩﻩﻩﻩﻩ//显示菜单
ﻩwhile
(1)
{
ClearLine();ﻩﻩ//清空结果显示区ﻩ
ﻩprintf("请选择操作:
(按‘Q'退出)");
ﻩcmd =getch();
ﻩClearLine();
ﻩfflush(stdin);
switch(cmd)
ﻩ{
case'0':
//随机创建一棵二叉树
ﻩﻩﻩwhile(cmd!
= 'y' &&cmd!
='Y')
ﻩﻩﻩﻩ{
ﻩProduce(str);ﻩ//随机产生二叉树先序序列
ﻩﻩCreateBiTree(T,str);// 用此序列建树
ﻩShowBiTree(T);ﻩﻩ//广义表形式显示
ﻩﻩprintf("使用创建的这个二叉树<Y/N>?
");
ﻩﻩﻩﻩcmd= getch();
ﻩﻩClearLine();
ﻩﻩ}
ﻩbreak;
ﻩﻩcase'2':
// 手动创建一棵二叉树
printf("请按二叉树先序序列输入二叉树:
(空结点用空格''表示)\n");
ﻩﻩCreateBiTree(T);
ﻩﻩﻩClearLine();
printf("二叉树创建成功!
\n");
ﻩShowBiTree(T);
ﻩﻩgetch();
ﻩbreak;
case'4':
//销毁二叉树
ﻩﻩDestroyBiTree(T);
ﻩﻩﻩprintf(" 二叉树已被销毁!
");
getch();
ﻩﻩbreak;
ﻩcase'6':
//判空
ﻩﻩﻩif(BiTreeEmpty(T))printf("二叉树是空二叉树。
");
ﻩﻩelseﻩprintf("二叉树非空");
ﻩgetch();
ﻩbreak;
ﻩﻩcase'8':
//求深度
ﻩﻩprintf("深度是%d",BiTreeDepth(T));
ﻩgetch();
ﻩﻩbreak;
ﻩcase'a':
//求左孩子
ﻩShowBiTree(T);
ﻩﻩprintf("你想求哪个字符的左孩子?
");
ﻩdo{
ﻩﻩﻩelem=getchar();
ﻩClearLine();
ﻩbt = SearchBiTree(T,elem);//查找指定的结点值elem
ﻩﻩif(!
bt) printf("你输入的结点不存在!
请重新输入:
");
ﻩﻩ}while(!
bt);
ﻩﻩClearLine();
ﻩﻩbt =LeftChild(T,bt);ﻩ// 求左孩子
ﻩﻩﻩif(bt)printf(" %c的左孩子是%c",elem,bt->data);
ﻩﻩﻩelseprintf("%c没有左孩子",elem);
ﻩﻩprintf("\n参照二叉树:
");
ﻩShowBiTree(T);
ﻩgetch();
ﻩbreak;
case 'c':
//求右孩子
ﻩShowBiTree(T);
ﻩﻩprintf(" 你想求哪个字符的右孩子?
");
ﻩdo{
ﻩelem = getchar();
ﻩClearLine();
ﻩﻩﻩbt= SearchBiTree(T,elem);
ﻩif(!
bt) printf(" 你输入的结点不存在!
请重新输入:
");
ﻩﻩﻩ}while(!
bt);
ﻩﻩClearLine();
ﻩbt=RightChild(T,bt);
ﻩﻩif(bt)printf("%c的右孩子是%c",elem,bt->data);
ﻩﻩelseﻩprintf("%c没有右孩子",elem);
ﻩﻩprintf("\n参照二叉树:
");
ﻩﻩShowBiTree(T);
ﻩﻩﻩgetch();
ﻩﻩbreak;
ﻩcase '1':
//先序遍历
ﻩﻩif(!
BiTreeEmpty(T))
ﻩ{
ﻩprintf("先序遍历序列为:
");
PreOrderTraverse(T,Visit);
ﻩﻩ}
ﻩﻩelseprintf("二叉树空,请先建树!
");
ﻩﻩgetch();
ﻩﻩbreak;
ﻩcase'3':
//中序遍历
ﻩﻩif(!
BiTreeEmpty(T))
{
ﻩﻩprintf("中序遍历序列为:
");
ﻩﻩInOrderTraverse(T,Visit);
ﻩﻩﻩﻩ}
ﻩﻩelseprintf("二叉树空,请先建树!
");
ﻩﻩgetch();
ﻩﻩbreak;
ﻩcase'5':
// 后序遍历
ﻩif(!
BiTreeEmpty(T))
ﻩﻩ{
ﻩﻩprintf("后序遍历序列为:
");
ﻩﻩﻩPostOrderTraverse(T,Visit);
ﻩﻩ}
ﻩﻩﻩelseprintf("二叉树空,请先建树!
");
ﻩﻩgetch();
ﻩbreak;
ﻩcase'7':
//层次遍历
if(!
BiTreeEmpty(T))
ﻩﻩﻩ{
ﻩﻩﻩprintf("层次遍历序列为:
");
ﻩﻩLevelOrderTraverse(T,Visit);
ﻩﻩﻩ}
else printf("二叉树空,请先建树!
");
ﻩﻩgetch();
ﻩbreak;
ﻩcase'9':
//插入一棵二叉树为另一棵二叉树的子树
ﻩﻩﻩdo{ﻩﻩ//随机创建一棵右孩子为空
ﻩﻩProduce(str);ﻩﻩﻩ//且层数小于4的树
ﻩﻩﻩﻩCreateBiTree(insert_bt,str);
ﻩﻩﻩﻩ}while(insert_bt->rchild||BiTreeDepth(insert_bt)>3);
ﻩﻩﻩprintf(" 先随机创建一棵右子树空的二叉树如图\n");
ﻩﻩﻩShowBiTree(insert_bt);ﻩﻩﻩ//新创建的树ﻩ
ﻩﻩﻩgetch();
ﻩﻩprintf("你想插入这棵树为原树哪个结点的子树:
\n");
ﻩﻩﻩShowBiTree(T);
ﻩﻩbt=SearchBiTree(T,getchar());
ﻩClearLine();
ﻩﻩprintf("你想插入为0. 左孩子 1. 右孩子 :
");
ﻩﻩfflush(stdin);
ﻩﻩﻩscanf("%d",&loc);
ﻩif(!
InsertChild(T,bt, loc, insert_bt))
ﻩprintf("插入出错!
");
ﻩelse{
ﻩﻩﻩClearLine();
ﻩﻩﻩﻩprintf(" 插入成功!
插入后T广义表形式为:
\n");
ﻩShowBiTree(T);
}
ﻩﻩgetch();
ﻩbreak;
ﻩﻩcase'b':
//删除指定结点的子树
ﻩﻩShowBiTree(T);
ﻩﻩﻩprintf("你想删除哪个结点的子树?
");
ﻩfflush(stdin);
ﻩﻩbt =SearchBiTree(T,getchar());
ﻩﻩprintf("\n你想删除0.左子树1.右子树:
");
ﻩﻩfflush(stdin);
ﻩﻩscanf("%d",&loc);
ﻩﻩClearLine();
ﻩif(!
DeleteChild(T,bt,loc))printf("删除出错!
");
ﻩﻩelseprintf("删除成功,检查结果\n");
ﻩﻩShowBiTree(T);
ﻩﻩgetch();
ﻩﻩﻩbreak;
ﻩﻩcase'e':
//返回先序序列第i个结点的值
ﻩﻩprintf("请输入一个结点的先序序列序号:
");
ﻩﻩscanf("%d",&loc);
temp=loc;
ﻩﻩClearLine();
ﻩﻩﻩelem=Value(T,temp);
ﻩprintf("参照二叉树:
");
ﻩﻩﻩShowBiTree(T);
ﻩﻩprintf("\n");
ﻩﻩﻩif(elem== '')ﻩprintf(" 该结点不存在。
");
ﻩﻩelse printf(" 先序序列第%d个结点值为%c",loc,elem);
ﻩﻩgetch();break;
ﻩﻩcase'd':
//结点赋值
ﻩShowBiTree(T);
ﻩﻩprintf("请输入要赋值的结点:
");
ﻩﻩdo{
ﻩelem=getchar();
ﻩﻩﻩClearLine();
ﻩbt=SearchBiTree(T,elem);
ﻩﻩﻩif(!
bt)printf("你输入的结点不存在!
请重新输入:
");
ﻩ}while(!
bt);;
ClearLine();
ﻩﻩﻩprintf(" 请输入新值:
");
ﻩfflush(stdin);
ﻩﻩelem=getchar();
ﻩAssign(T,bt,elem);
ﻩﻩprintf(" 赋值成功,请查看二叉树状态.\n");
ﻩﻩShowBiTree(T);
ﻩﻩﻩgetch();
ﻩﻩbreak;
case'Q':
//退出
ﻩcase'q':
exit(0);ﻩﻩ
}
ﻩ}
return0;
}
voidﻩMenu()
// 显示菜单函数
{
ﻩprintf("0.随机创建CreateBiTree() 1. 先序遍历PreOrderTraverse()");
printf("\n\n2.手动创建CreateBiTree() 3. 中序遍历InOrderTraverse()");
ﻩprintf("\n\n4. 销毁 DestoryBiTree()5.后序遍历PostOrderTraverse()");
ﻩprintf("\n\n6.判空 BiTreeEmpty() 7. 层次遍历LevelOrderTraverse()");
printf("\n\n8. 求深度 BiTreeDepth() 9.插入子树InsertChild()");
printf("\n\n a.求左孩子LeftChild() b.删除子树DeleteChild()");
printf("\n\nc.求右孩子 RightChild()d.结点赋值Assign()");
ﻩprintf("\n\ne. 求结点值 Value()");
ﻩprintf("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
voidﻩProduce(char*str)
//用随机数产生二叉树层次字符序列
//使所有节点的字符不相同,空节点用‘&’表示
{
intﻩﻩexist[27],i ,elem, maxnodes=rand()%41;
ﻩwhile(maxnodes<15||maxnodes >31) maxnodes= rand()%41;
ﻩ/* 随机产生一个大于15小于31的随机数作为结点个数 */
for(i =0;i<27;i++)exist[i]=0;ﻩ//初始化存在数组,用于使所有结点值不同
i=1;
ﻩwhile(i<maxnodes)
ﻩﻩ{
elem=rand() % 26 ;
ﻩif(!
exist[elem]&&str[i/2]!
='&')// 结点未生成且存在父节点
ﻩﻩ{
ﻩstr[i++]=elem+ 'A';
ﻩexist[elem]=1;
ﻩ}
ﻩelsestr[i++]='&';
ﻩ}
str[i]='\0';
}
头文件:
base.h:
#include"stdio.h"
#include"conio.h"
#include"stdlib.h"
#include"windows.h"
#include"malloc.h"
#include"math.h"
#defineOKﻩﻩ1
#defineTRUEﻩ1
#defineﻩERRORﻩﻩ0
#defineFALSEﻩﻩ0
#defineﻩMAXSIZEﻩﻩ100ﻩﻩﻩ
typedefintStatus;
typedefﻩcharﻩﻩTElemType;
shortﻩwherex()ﻩ//返回光标的x坐标
{
ﻩCONSOLE_SCREEN_BUFFER_INFO csbinfo;
ﻩGetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&csbinfo);
returncsbinfo.dwCursorPosition.X;
}
shortﻩwherey()ﻩ//返回光标的y坐标
{
ﻩCONSOLE_SCREEN_BUFFER_INFOcsbinfo;
ﻩGetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&csbinfo);
return csbinfo.dwCursorPosition.Y;
}
void gotoxy(short x,shorty)//移动光标到(x,y)坐标
{
ﻩCOORD point= {x,y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), point);
}
void ClearLine(unsignedy= 17)
//清除第y行与y+1行的字符,并使光标在行首,默认清除第17至19行
{
ﻩfor(inti=0;i < 256;i++)
ﻩ{
ﻩgotoxy(i,y);
putchar(' ');
}
gotoxy(0,wherey()-3);
}
voidClearAera(unsignedx =96,unsigned y=17)
//清除(0,y)-(x,y+1)区域的字符,并使光标移动到y
{
for(unsignedi=0; i{
gotoxy(i%(x/2),y+(i/48));
putchar(' ');
ﻩ}
ﻩgotoxy(0,y);
}
StatusVisit(TElemTypee)
//二叉树结点visit函数,显示字符的值
{
printf("%c",e);
ﻩreturn OK;
}
******************华丽的分割线***********************
bitree.h:
typedef charTElemType;
typedefstructﻩBiTNode
{
TElemTypeﻩdata;
structﻩBiTNodeﻩ*lchild;
ﻩstructﻩﻩBiTNode*rchild;//左右孩子指针
}BiTNode, *BiTree;ﻩ
voidﻩInitBiTree(BiTree&T)
//构造空二叉树T
{
T=NULL;
}
StatusDestroyBiTree(BiTree&T)
//销毁二叉树T
{
if(!
T)returnERROR;
ﻩDestroyBiTree(T->lchild);ﻩﻩ//删除左子树
DestroyBiTree(T->rchild);ﻩﻩ//删除右子树
ﻩfree(T);
T=NULL;
ﻩreturnOK;
}
StatusCreateBiTree(BiTree&T)
// 先序建立二叉树T,空格表示空结点
{
TElemType ch;
fflush(stdin);
ﻩch=getche();
if(ch=='')T=NULL;
else{
T=(BiTree)malloc(sizeof(BiTNode));
if(!
T)exit(OVERFLOW);
ﻩﻩT->data=ch;ﻩ//生成头结点
ﻩCreateBiTree(T->lchild);ﻩ//构造左子树
CreateBiTree(T->rchild);ﻩ// 构造右子树
ﻩ}
returnOK;
}
StatusﻩCreateBiTree(BiTree&T,char *str,unsignedi=1)
//str储存着二叉树的层次序列,str[i]=='&'表示结点不存在
//i为当前要创建结点对应的数组序号节点
//由字符数组str先序建立一棵二叉树T
{
ﻩif(str[i]=='&'||i>=strlen(str))T=NULL;ﻩ//第i个结点不存在
else{
ﻩT=(BiTree)malloc(sizeof(BiTNode));
ﻩif(!
T)exit(OVERFLOW);
ﻩT->data = str[i];ﻩﻩ//生成根节点
CreateBiTree(T->lchild,str, i*2);ﻩﻩﻩ// 构造左子树
ﻩﻩCreateBiTree(T->rchild, str,i*2+1);ﻩﻩ//构造右子树
ﻩ}
ﻩreturnOK;}