数据结构实验报告二叉排序树.docx
《数据结构实验报告二叉排序树.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告二叉排序树.docx(21页珍藏版)》请在冰豆网上搜索。
![数据结构实验报告二叉排序树.docx](https://file1.bdocx.com/fileroot1/2022-12/11/04615123-c79e-4094-9e97-8223328a2736/04615123-c79e-4094-9e97-8223328a27361.gif)
数据结构实验报告二叉排序树
《数据结构》实验报告
◎实验题目:
创建一个二叉排序树,并以先序、中序、后序遍历输出。
◎实验目的:
熟练掌握二叉排序树建立的算法
◎实验内容:
已知n个元素,创建一个二叉排序树,以先序、中序、后序遍历输出,
并计算每个节点的平衡因子。
一、需求分析
1.本程序输入应为一组数,将这组数作为关键字创建一个二叉排序树。
2.本程序输出应为该建立好的二叉排序树的先序、中序、后序遍历输出,以及每个节点的平衡因子。
3.程序执行的命令包括:
(1)创建二叉排序树
(2)先序非递归遍历输出(3)中序非递归遍历输出(4)后序非递归遍历输出(5)计算并输出每个节点的平衡因子
4.测试数据:
输入元素的个数为8,元素为5325762048146084
输出为:
先序遍历:
5325201448766084
中序遍历:
1420254853607684
后序遍历:
1420482560847653
平衡因子:
节点53的平衡因子为1
节点25的平衡因子为1
节点20的平衡因子为1
节点14的平衡因子为0
节点48的平衡因子为0
节点76的平衡因子为0
节点60的平衡因子为0
节点84的平衡因子为0
二概要设计
为了实现以上操作,应以二叉链表为存储结构。
1.基本操作:
node*create()
创建二叉排序树
voidNRPreorder(node*bt)
先序非递归遍历输出
voidNRinorder(node*bt)
中序非递归遍历输出
voidNRpostorder(node*bt)
后序非递归遍历输出
intheight(node*bt)
计算左右子树深度
voidshendu(node*bt)
计算平衡因子
2.本程序包含七个模块
(1)主程序模块
(2)二叉排序树创建模块
(3)
先序遍历模块
(4)中序遍历模块
(5)后序遍历模块
(6)
计算左右子树深度模块
(7)计算平衡因子模块
3.
模块调用图
三详细设计
1.元素类型,结点类型和指针类型:
#definemaxsize100
typedefstructnode
{
chardata;
structnode*lc;
structnode*rc;
}node;
node*s[maxsize];
node*bt;
node*q,*p;
2.每个模块的分析:
(1)主程序模块:
intmain()
{
node*bt;
bt=create();
printf("该二叉树的先序递归遍历序列为:
");
preorder(bt);
printf("\n");
printf("该二叉树的中序递归遍历序列为:
");
inorder(bt);
printf("\n");
printf("该二叉树的后序递归遍历序列为:
");
postorder(bt);
printf("\n");
printf("该二叉树的先序非递归遍历序列为:
");
NRPreorder(bt);
printf("\n");
printf("该二叉树的中序非递归遍历序列为:
");
NRinorder(bt);
printf("\n");
printf("该二叉树的后序非递归遍历序列为:
");
NRpostorder(bt);
printf("\n");
printf("以先序遍历输出该二叉树,每个节点的平衡因子如下:
\n");
shendu(bt);
getchar();
getchar();
return0;
}
(2)二叉排序树创建模块:
node*create()
{
node*bt;
node*q,*p;
bt=NULL;/*根节点指针置空*/
intx;
inti;
intm;
intj;
printf("请输入数据个数:
\n");
scanf("%d",&m);
printf("请输入数据:
\n");
for(j=0;j{
scanf("%d",&x);
i=0;
q=(node*)malloc(sizeof(node));/*申请新节点,将新节点数据域赋值,左右孩子置空*/
q->data=x;
q->lc=q->rc=NULL;
if(bt==NULL)/*如果根节点指针为空,将其指向新申请节点*/
bt=q;
else
{
p=bt;/*活动指针指向根节点*/
while(i==0)
{
if(p->data>x)/*如果新输入的数值比当前节点的数值小*/
{
if(p->lc!
=NULL)/*如果当前节点的左孩子不为空,将活动指针移到它的左孩子*/
p=p->lc;
else/*否则将新申请节点链到当前节点的左孩子,将i标记为1,表示已处理*/
{
p->lc=q;
i=1;
}
}
else/*否则沿右链域比较*/
{
if(p->rc!
=NULL)
p=p->rc;
else/*直到终端,插入输入节点*/
{
p->rc=q;
i=1;
}
}
}
}
}
returnbt;
}
(3)先序遍历模块:
voidNRPreorder(node*bt)
{
node*p;
top=-1;
top++;
s[top]=bt;
while(top!
=-1)
{
p=s[top--];
while(p)
{
printf("%d",p->data);
top++;
s[top]=p->rc;
p=p->lc;
}
}
}
(4)中序遍历模块
voidNRinorder(node*bt)
{
node*p;
inttop;
if(bt==NULL)return;
top=0;
p=bt;
while(!
(p==NULL&&top==0))
{
while(p!
=NULL)
{
s[top]=p;
top++;
p=p->lc;
}
if(top<=0)return;
else
{
top--;
p=s[top];
printf("%d",p->data);
p=p->rc;
}
}
}
(5)后序遍历模块:
voidNRpostorder(node*bt)
{
node*p,*q;
inttop=-1;
intflag;
p=bt;
if(p!
=NULL)
{
do
{
while(p!
=NULL)
{
top++;
s[top]=p;
p=p->lc;
}
q=NULL;
flag=1;
while(top!
=-1&&flag)
{
p=s[top];
if(p->rc==q)
{
printf("%d",p->data);
top--;
q=p;
}
else
{
p=p->rc;
flag=0;
}
}
}while(top!
=-1);
}
}
(6)计算左右子树深度模块
intheight(node*bt)
{
inthl,hr;
if(bt==NULL)/*利用递归算法求左右子树的深度*/
return0;
else
{
hl=height(bt->lc);
hr=height(bt->rc);
if(hl>hr)
return(hl+1);
else
return(hr+1);
}
}
(7)计算平衡因子模块
voidshendu(node*bt)
{
intsl,sr;
intph;
node*p;
top=-1;
top++;
s[top]=bt;
while(top!
=-1)
{
p=s[top--];
while(p)
{
sl=height(p->lc);/*当前节点左子树的深度*/
sr=height(p->rc);/*当前节点右子树的深度*/
ph=sl-sr;/*当前节点的平衡因子*/
printf("节点为%d的平衡因子为%d\n",p->data,ph);
top++;
s[top]=p->rc;
p=p->lc;
}
}
}
3.函数调用图:
4.完整的程序:
(见源文件).
四使用说明、测试分析及结果
1.程序使用说明
(1)本程序的运行环境为VC6.0。
(2)进入演示程序后即显示提示信息:
请输入数据个数:
请输入数据:
输入完数据以三种形式输出二叉排序树,并输出每个节点的平衡因子.
2.测试数据:
输入元素的个数为8,元素为5325762048146084
输出为:
先序遍历:
5325201448766084
中序遍历:
1420254853607684
后序遍历:
1420482560847653
平衡因子:
节点53的平衡因子为1
节点25的平衡因子为1
节点20的平衡因子为1
节点14的平衡因子为0
节点48的平衡因子为0
节点76的平衡因子为0
节点60的平衡因子为0
节点84的平衡因子为0
3.运行界面:
五、实验总结
本次试验过程比较顺利,由于上次的二叉树积累了经验,所以这次编得比较快,编程过程中没有出现问题,通过这次编程对于二叉树有了更进一步的熟悉和了解,可以熟练编写二叉排序树,熟悉了二叉排序树的结构,并且对于计算节点的深度以及节点的平衡因子有了一定的掌握。
教师评语:
实验成绩:
#include
#include
#definemaxsize100
//定义结构体
typedefstructnode
{
chardata;
structnode*lc;
structnode*rc;
}node;
//定义栈
node*s[maxsize];
inttop=-1;
//创建二叉排序树
node*create()
{
node*bt;
node*q,*p;
bt=NULL;/*根节点指针置空*/
intx;
inti;
intm;
intj;
printf("请输入数据个数:
\n");
scanf("%d",&m);
printf("请输入数据:
\n");
for(j=0;j{
scanf("%d",&x);
i=0;
q=(node*)malloc(sizeof(node));/*申请新节点,将新节点数据域赋值,左右孩子置空*/
q->data=x;
q->lc=q->rc=NULL;
if(bt==NULL)/*如果根节点指针为空,将其指向新申请节点*/
bt=q;
else
{
p=bt;/*活动指针指向根节点*/
while(i==0)
{
if(p->data>x)/*如果新输入的数值比当前节点的数值小*/
{
if(p->lc!
=NULL)/*如果当前节点的左孩子不为空,将活动指针移到它的左孩子*/
p=p->lc;
else/*否则将新申请节点链到当前节点的左孩子,将i标记为1,表示已处理*/
{
p->lc=q;
i=1;
}
}
else/*否则沿右链域比较*/
{
if(p->rc!
=NULL)
p=p->rc;
else/*直到终端,插入输入节点*/
{
p->rc=q;
i=1;
}
}
}
}
}
returnbt;
}
//先序递归遍历
voidpreorder(node*bt)
{
if(bt!
=NULL)
{
printf("%d",bt->data);
preorder(bt->lc);
preorder(bt->rc);
}
}
//中序递归遍历
voidinorder(node*bt)
{
if(bt!
=NULL)
{
inorder(bt->lc);
printf("%d",bt->data);
inorder(bt->rc);
}
}
//后序递归遍历
voidpostorder(node*bt)
{
if(bt!
=NULL)
{
postorder(bt->lc);
postorder(bt->rc);
printf("%d",bt->data);
}
}
//先序非递归遍历
voidNRPreorder(node*bt)
{
node*p;
top=-1;
top++;
s[top]=bt;
while(top!
=-1)
{
p=s[top--];
while(p)
{
printf("%d",p->data);
top++;
s[top]=p->rc;
p=p->lc;
}
}
}
//中序非递归遍历
voidNRinorder(node*bt)
{
node*p;
inttop;
if(bt==NULL)return;
top=0;
p=bt;
while(!
(p==NULL&&top==0))
{
while(p!
=NULL)
{
s[top]=p;
top++;
p=p->lc;
}
if(top<=0)return;
else
{
top--;
p=s[top];
printf("%d",p->data);
p=p->rc;
}
}
}
//后序非递归遍历
voidNRpostorder(node*bt)
{
node*p,*q;
inttop=-1;
intflag;
p=bt;
if(p!
=NULL)
{
do
{
while(p!
=NULL)
{
top++;
s[top]=p;
p=p->lc;
}
q=NULL;
flag=1;
while(top!
=-1&&flag)
{
p=s[top];
if(p->rc==q)
{
printf("%d",p->data);
top--;
q=p;
}
else
{
p=p->rc;
flag=0;
}
}
}while(top!
=-1);
}
}
//计算平衡因子
intheight(node*bt)
{
inthl,hr;
if(bt==NULL)/*利用递归算法求左右子树的深度*/
return0;
else
{
hl=height(bt->lc);
hr=height(bt->rc);
if(hl>hr)
return(hl+1);
else
return(hr+1);
}
}
voidshendu(node*bt)
{
intsl,sr;
intph;
node*p;
top=-1;
top++;
s[top]=bt;
while(top!
=-1)
{
p=s[top--];
while(p)
{
sl=height(p->lc);/*当前节点左子树的深度*/
sr=height(p->rc);/*当前节点右子树的深度*/
ph=sl-sr;/*当前节点的平衡因子*/
printf("节点为%d的平衡因子为%d\n",p->data,ph);
top++;
s[top]=p->rc;
p=p->lc;
}
}
}
intmain()
{
node*bt;
bt=create();
printf("该二叉树的先序递归遍历序列为:
");
preorder(bt);
printf("\n");
printf("该二叉树的中序递归遍历序列为:
");
inorder(bt);
printf("\n");
printf("该二叉树的后序递归遍历序列为:
");
postorder(bt);
printf("\n");
printf("该二叉树的先序非递归遍历序列为:
");
NRPreorder(bt);
printf("\n");
printf("该二叉树的中序非递归遍历序列为:
");
NRinorder(bt);
printf("\n");
printf("该二叉树的后序非递归遍历序列为:
");
NRpostorder(bt);
printf("\n");
printf("以先序遍历输出该二叉树,每个节点的平衡因子如下:
\n");
shendu(bt);
getchar();
getchar();
return0;
}