二叉树的随机生成及其遍历.docx
《二叉树的随机生成及其遍历.docx》由会员分享,可在线阅读,更多相关《二叉树的随机生成及其遍历.docx(15页珍藏版)》请在冰豆网上搜索。
二叉树的随机生成及其遍历
张zhaohan10804XXXXX
2010/6/12
问题重述
利用随机函数产生50个(不大于100且各不相同的)随机整数,用这些整数来生成一棵二叉树,分别对二叉树进行先根遍历,中根遍历和后根遍历并输出树中结点元素序列。
程序设计
(一)需求分析:
5、
•问题的定义与要求:
1、产生50个不大于100且各不相同的随机整数(由系统的随机函数生成并对100取模);2、先根遍历并输出结果;3、中根遍历并输出结果;4、后根遍历并输出结果;按层次浏览二叉树结点;6、退出程序。
•俞入:
所需功能,选项为1〜6。
•输出:
按照用户功能选择输出结果。
•限制:
输入的功能选择在1〜6之间,否则无回应。
•模块功能及要求:
RandDif():
生成50个随机不大于100的整数,每次生成不同随机整数。
CreateBitree():
给数据结点生成二叉树,使每个结点的左右儿子指针指向左右儿子。
NRPreOrder():
非递归算法的先根遍历。
inOrderTraverse():
递归算法的中根遍历。
PostOrderTraverse():
递归算法的后根遍历。
Welcome():
欢迎窗口。
Menu():
菜单。
Goodbye():
再见窗口。
(二)概要设计:
首先要生成二叉树,由于是对随机生成的50个数生成二叉树,故可以采取顺序存储的方式,对结点的左右儿子进行赋值。
生成的二叉树是完全二叉树。
先根遍历的非递归算法:
1、根结点进栈
2、结点出栈,被访问
3、结点的右、左儿子(非空)进栈
4、反复执行2、3,至栈空为止。
先根遍历的算法流程图:
根结点进栈(a[0]=T->boot,p=a[0])
访问结点printf(*p)
右儿子存在则进栈a[i]=(*p).rchild;i++;
左儿子存在则进栈a[i]=(*p).rchild;i++;
栈顶降低top--:
i--;p=a[i];
栈非空while(i>-1)
返回
中根遍历的递归算法流程图:
T为空
Y
N
Return;
inOrderTraverse(T->lchild)
Printf(T->data)inOrderTraverse(T->rchild)
后根遍历的递归算法流程图:
inOrderTraverse(T->rchild)
Printf(T->data)
遍历输出均按链式存储。
链式存储的特点是借助指示元素存储地址的指针(pointer)表示数组元素之间的逻辑关系。
按层次查看二叉树元素则按下标顺序直接输出。
同时,生成随机数、生成二叉树均是按顺序存储。
顺序存储的特点是借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系。
(三)详细设计
程序源代码设计:
(1)定义结点:
structdata
{
intn;
structdata*lchild;
structdata*rchild;
}data[N];
(2)产生随机数RandDif(structdatadata[])inti,j;
srand((int)time(0));for(i=0;i{data[i].n=rand()%100;for(j=i-1;j>1;j--)if(data[i].n==data[j].n||data[i].n==0){i--;j=0;}}}(3)生成二叉树CreateBitree(structdatadata[])inti;for(i=0;i<25;i++)data[i].lchild=&data[2*i+1];data[i].rchild=&data[2*i+2];}printf("\nSuccessfullycreateaBinaryTree.\n");printf("TheBinaryTreehas50differentelement.");}(4)先根遍历的非递归算法NRPreOrder(structdatadata[])inti=0;structdata*a[N],*p=&data[0];while(i>-1){printf("%-4d",(*p).n);if((*(*p).rchild).n)a[i]=(*p).rchild;i++;}if((*(*p).lchild).n)a[i]=(*p).lchild;i++;}i--;p=a[i];/}}(5)先根遍历的递归算法PreOrderTraverse(structdatadata)if(data.n){printf("%-4d",data.n);PreOrderTraverse(*(data.lchild));PreOrderTraverse(*(data.rchild));}}(6)中根遍历的递归算法inOrderTraverse(structdatadata){if(data.n){inOrderTraverse(*(data.lchild));printf("%-4d",data.n);inOrderTraverse(*(data.rchild));}}(7)后根遍历的递归算法PostOrderTraverse(structdatadata)if(data.n){PostOrderTraverse(*(data.lchild));PostOrderTraverse(*(data.rchild));printf("%-4d",data.n);}}(四)测试结果:由于先、中、后根遍历递归算法类似,故此处,选择中根遍历递归算法进行测试:如某次生成的50个数为:28969760436590701191643744948156631428736764134575885777865569239831858128795193340181772211058而生成的二叉树为:289697604365907011916437449469239831858128795193340181772211058图:二叉树中根遍历结果为:69812370985631608563811121487969285191937334340671861764722821131045845657537889757447790869455而程序中根遍历结果为:69812370985631608563811121487969285191937334340671861764722821131045845657537889757447790869455完全符合,递归算法测试完毕。验证先根遍历的非归算法:在main()中加入先根递归算法和非递归算法作结果比较。由于递归算法已经验证,故此处只须非递归算法和递归算法结果符合即可。生成50个数:112387972861341175875886382505761919214286846993025202485635399496031909676369883278422562187递归算法的先根遍历结果:112794826355039911574960643190727919676923698581483272884223886756856214687889930136252032485非递归算法的先根遍历结果:112794826355039911574960643190727919676923698581483272884223886756856214687889930136252032485在生成50个随机不同整数的过程中遇到了几次问题,如循环条件差一个数,就会导致生成数中有几个数是相同的,此时就需要修改循环条件;数据要排除0。函数的参数传递存在一定误区,有几次传递参数不当,格式不符,导致不能得到结果,在认清了函数参数传递的要求后问题得以解决。调试的时候为发现各个细节问题,会在各个模块的容易出问题的过程加输出函数,就便于发现问题所在。易知生成随机数的时间复杂度为,生成二叉树的时间复杂度为0(n),递归遍历的时间复杂度均为0(n),而非递归先根遍历的时间复杂度也为0(n)。附:完整程序代码:/*利用随机函数产生50个(不大于100且各不相同的)随机整数,用这些整数来生成一棵二树,分别对二叉树进行先根遍历,中根遍历和后根列遍历输出树中结点元素序列。先根遍历输出要求采用非递归来实现。#include#include#include#include#defineN50#defineNULL0structdata{intn;structdata*lchild;structdata*rchild;}data[N];/*定义数组元素*/voidRandDif(structdatadata[]){/*生成个互不相同的随机整数*/inti,j;srand((int)time(0));/*每次生成不同的随机数*/for(i=0;i{data[i].n=rand()%100;for(j=i-1;j>-1;j--)if(data[i].n==data[j].n||data[i].n==0){i--;j=0;}}}voidCreateBitree(structdatadata[]){/*生成二树*/inti;for(i=0;i<25;i++){/*将结点的左右儿子指针指向相应的左右儿子*/data[i].lchild=&data[2*i+1];data[i].rchild=&data[2*i+2];}printf("\nSuccessfullycreateaBinaryTree.\n");printf("TheBinaryTreehas50differentelement.");}voidNRPreOrder(structdatadata[]){/*先根遍历输出,非递归算法*/inti=0;structdata*a[N],*p=&data[0];while(i>-1){printf("%-4d",(*p).n);if((*(*p).rchild).n){/*存在右儿子,则右儿子进栈*/a[i]=(*p).rchild;i++;}if((*(*p).lchild).n){/*存在右儿子,则左儿子进栈*/a[i]=(*p).lchild;i++;}i--;p=a[i];/*出栈,栈顶指针下移*/}voidPreOrderTraverse(structdatadata){/*先根遍历输出,递归算法*/if(data.n){printf("%-4d",data.n);PreOrderTraverse(*(data.lchild));/*先根遍历右子树*/PreOrderTraverse(*(data.rchild));/*先根遍历左子树*/}}voidinOrderTraverse(struct{/*中跟遍历输出,递归算法*/if(data.n){inOrderTraverse(*(data.lchild));printf("%-4d",data.n);inOrderTraverse(*(data.rchild));}}voidPostOrderTraverse(struct{/*后根遍历输出,递归算法*/if(data.n){PostOrderTraverse(*(data.lchild));PostOrderTraverse(*(data.rchild));printf("%-4d",data.n);}}datadata)/*中跟遍历左子树*//*中跟遍历右子树*/datadata)/*后根遍历左子树*//*后根遍历右子树*/voidWelcome(){/*欢迎窗口*/printf("\n\nWelcomeuseTraverseBinaryTree\n\n");printf("\n\n\n\n");printf("\n");printf("Specialty:InformationandComputationalScienceProgram\n");printf(printf(Class:2Grade:2No.:200530760214Name:LinWeiyang\n"Pressanykeytocontinue...\n");); getch();}voidMenu(){/*菜单*/printf(***************************************************************\n"printf(Pleaseselectthefunctionyouneed:**\n"printf(**1.Createanothertree.**\n"printf(**2.PreordertraversetheBinaryTree.**\n"printf(**3.InordertraversetheBinaryTree.**\n"printf(**4.PostordertraversetheBinaryTree.**\n"printf(**5.DisplaytheBinaryTree.**\n"printf("**6.Exit.**\n"printf(***************************************************************\n");););););););););voidGoodbye(){/*再见窗口*/printf("\n");printf("\n");printf(I!TTTTTTTTTTTTTTTTTTTTTT\n"printf(I!TTTTTTTTTTTTTTTTTTTTT\n"printf(TTTTTTTTTTTTTTTTTTTTTT\n"printf(TTTTTTTTTTTTTTTTTTTTTTTT\nprintf(TTTTTTTTTTTTTTTTTTTTTTT\n"printf(I!TTTTTTTTTTTTTTTTTTTT\n"printf(I!TTTTTTTTTTTTTTTTTTTTTT\n"printf(TTTTTTTTTTTTTTTTTTTTTT\n"printf("\n");printf("\n");printf(TTTTTTTTTTTTTTTTTTTTTTTT\n"Copyright2010ZhangZhaohan\n"printf();););););););););printf(getch();Pressanykeytoexit...\n"););voidmain(){inti;Welcome();Loop: clrscr();Menu();switch(getch()) getch();gotoLoop;break;case'6':;break;default:gotoLoop;clrscr();Goodbye();可执行文件:程序运行截图:运行窗口:先根遍历
{data[i].n=rand()%100;
for(j=i-1;j>1;j--)if(data[i].n==data[j].n||data[i].n==0){i--;j=0;}}
}
(3)生成二叉树CreateBitree(structdatadata[])inti;
for(i=0;i<25;i++)data[i].lchild=&data[2*i+1];data[i].rchild=&data[2*i+2];
printf("\nSuccessfullycreateaBinaryTree.\n");printf("TheBinaryTreehas50differentelement.");}
(4)先根遍历的非递归算法NRPreOrder(structdatadata[])inti=0;
structdata*a[N],*p=&data[0];while(i>-1)
{printf("%-4d",(*p).n);
if((*(*p).rchild).n)
a[i]=(*p).rchild;
i++;
if((*(*p).lchild).n)
a[i]=(*p).lchild;
i--;p=a[i];/}}
(5)先根遍历的递归算法PreOrderTraverse(structdatadata)if(data.n)
printf("%-4d",data.n);
PreOrderTraverse(*(data.lchild));
PreOrderTraverse(*(data.rchild));
(6)中根遍历的递归算法inOrderTraverse(structdatadata)
if(data.n)
inOrderTraverse(*(data.lchild));
inOrderTraverse(*(data.rchild));
(7)后根遍历的递归算法PostOrderTraverse(structdatadata)
PostOrderTraverse(*(data.lchild));
PostOrderTraverse(*(data.rchild));
(四)测试结果:
由于先、中、后根遍历递归算法类似,故此处,选择中根遍历递归算法进行测试:
如某次生成的50个数为:
28969760436590701191643744948156631428736764
134575885777865569239831858128795193340181772211058
而生成的二叉树为:
28
96
97
60
43
65
90
70
11
91
6
437
44
94
69239831858128795193340181772211058
图:
二叉树
中根遍历结果为:
6981237098563160856381112148796928519193733434067
1861764722821131045845657537889757447790869455而程序中根遍历结果为:
698123709856316085638111214879692851919373343
40671861764722821131045845657537889757447790869455完全符合,递归算法测试完毕。
验证先根遍历的非归算法:
在main()中加入先根递归算法和非递归算法作结果比较。
由于递归算法已经验证,故此处
只须非递归算法和递归算法结果符合即可。
生成50个数:
11238797286134117587588638250576191921428684699302520
2485635399496031909676369883278422562187
递归算法的先根遍历结果:
1127948263550399115749606431907279196769236
98581483272884223886756856214687889930136252032485
非递归算法的先根遍历结果:
11279482635503991157496064319072791967692
3698581483272884223886756856214687889930136252032485
在生成50个随机不同整数的过程中遇到了几次问题,如循环条件差一个数,就会导致生成数中有几个数是相同的,此时就需要修改循环条件;数据要排除0。
函数的参数传递存在一定误区,有几次传递参数不当,格式不符,导致不能得到结果,在认清了函数参数传递的要求后问题得以解决。
调试的时候为发现各个细节问题,会在各个模块的容易出问题的过程加输出函数,就便于发现问题所在。
易知生成随机数的时间复杂度为,生成二叉树的时间复杂度为0(n),递归遍历的时间复杂
度均为0(n),而非递归先根遍历的时间复杂度也为0(n)。
附:
完整程序代码:
/*利用随机函数产生50个(不大于100且各不相同的)随机整数,用这些整数来生成一棵二树,分别对二叉树进行先根遍历,中根遍历和后根列遍历输出树中结点元素序列。
先根遍历输出要求采用非递归来实现。
#include
#defineN50
#defineNULL0
}data[N];/*定义数组元素*/
voidRandDif(structdatadata[])
{/*生成个互不相同的随机整数*/
inti,j;
srand((int)time(0));/*每次生成不同的随机数*/
for(i=0;i{data[i].n=rand()%100;for(j=i-1;j>-1;j--)if(data[i].n==data[j].n||data[i].n==0){i--;j=0;}}}voidCreateBitree(structdatadata[]){/*生成二树*/inti;for(i=0;i<25;i++){/*将结点的左右儿子指针指向相应的左右儿子*/data[i].lchild=&data[2*i+1];data[i].rchild=&data[2*i+2];}printf("\nSuccessfullycreateaBinaryTree.\n");printf("TheBinaryTreehas50differentelement.");}voidNRPreOrder(structdatadata[]){/*先根遍历输出,非递归算法*/inti=0;structdata*a[N],*p=&data[0];while(i>-1){printf("%-4d",(*p).n);if((*(*p).rchild).n){/*存在右儿子,则右儿子进栈*/a[i]=(*p).rchild;i++;}if((*(*p).lchild).n){/*存在右儿子,则左儿子进栈*/a[i]=(*p).lchild;i++;}i--;p=a[i];/*出栈,栈顶指针下移*/}voidPreOrderTraverse(structdatadata){/*先根遍历输出,递归算法*/if(data.n){printf("%-4d",data.n);PreOrderTraverse(*(data.lchild));/*先根遍历右子树*/PreOrderTraverse(*(data.rchild));/*先根遍历左子树*/}}voidinOrderTraverse(struct{/*中跟遍历输出,递归算法*/if(data.n){inOrderTraverse(*(data.lchild));printf("%-4d",data.n);inOrderTraverse(*(data.rchild));}}voidPostOrderTraverse(struct{/*后根遍历输出,递归算法*/if(data.n){PostOrderTraverse(*(data.lchild));PostOrderTraverse(*(data.rchild));printf("%-4d",data.n);}}datadata)/*中跟遍历左子树*//*中跟遍历右子树*/datadata)/*后根遍历左子树*//*后根遍历右子树*/voidWelcome(){/*欢迎窗口*/printf("\n\nWelcomeuseTraverseBinaryTree\n\n");printf("\n\n\n\n");printf("\n");printf("Specialty:InformationandComputationalScienceProgram\n");printf(printf(Class:2Grade:2No.:200530760214Name:LinWeiyang\n"Pressanykeytocontinue...\n");); getch();}voidMenu(){/*菜单*/printf(***************************************************************\n"printf(Pleaseselectthefunctionyouneed:**\n"printf(**1.Createanothertree.**\n"printf(**2.PreordertraversetheBinaryTree.**\n"printf(**3.InordertraversetheBinaryTree.**\n"printf(**4.PostordertraversetheBinaryTree.**\n"printf(**5.DisplaytheBinaryTree.**\n"printf("**6.Exit.**\n"printf(***************************************************************\n");););););););););voidGoodbye(){/*再见窗口*/printf("\n");printf("\n");printf(I!TTTTTTTTTTTTTTTTTTTTTT\n"printf(I!TTTTTTTTTTTTTTTTTTTTT\n"printf(TTTTTTTTTTTTTTTTTTTTTT\n"printf(TTTTTTTTTTTTTTTTTTTTTTTT\nprintf(TTTTTTTTTTTTTTTTTTTTTTT\n"printf(I!TTTTTTTTTTTTTTTTTTTT\n"printf(I!TTTTTTTTTTTTTTTTTTTTTT\n"printf(TTTTTTTTTTTTTTTTTTTTTT\n"printf("\n");printf("\n");printf(TTTTTTTTTTTTTTTTTTTTTTTT\n"Copyright2010ZhangZhaohan\n"printf();););););););););printf(getch();Pressanykeytoexit...\n"););voidmain(){inti;Welcome();Loop: clrscr();Menu();switch(getch()) getch();gotoLoop;break;case'6':;break;default:gotoLoop;clrscr();Goodbye();可执行文件:程序运行截图:运行窗口:先根遍历
data[i].n=rand()%100;
for(j=i-1;j>-1;j--)if(data[i].n==data[j].n||data[i].n==0){i--;j=0;}
voidCreateBitree(structdatadata[])
{/*生成二树*/
inti;
for(i=0;i<25;i++)
{/*将结点的左右儿子指针指向相应的左右儿子*/data[i].lchild=&data[2*i+1];
data[i].rchild=&data[2*i+2];
printf("\nSuccessfullycreateaBinaryTree.\n");
printf("TheBinaryTreehas50differentelement.");
voidNRPreOrder(structdatadata[])
{/*先根遍历输出,非递归算法*/
inti=0;
structdata*a[N],*p=&data[0];
while(i>-1)
printf("%-4d",(*p).n);
{/*存在右儿子,则右儿子进栈*/a[i]=(*p).rchild;
{/*存在右儿子,则左儿子进栈*/a[i]=(*p).lchild;
i--;p=a[i];/*出栈,栈顶指针下移*/
voidPreOrderTraverse(structdatadata)
{/*先根遍历输出,递归算法*/
PreOrderTraverse(*(data.lchild));/*先根遍历右子树*/
PreOrderTraverse(*(data.rchild));/*先根遍历左子树*/
voidinOrderTraverse(struct{/*中跟遍历输出,递归算法*/if(data.n)
{inOrderTraverse(*(data.lchild));printf("%-4d",data.n);inOrderTraverse(*(data.rchild));
voidPostOrderTraverse(struct
{/*后根遍历输出,递归算法*/
PostOrderTraverse(*(data.lchild));PostOrderTraverse(*(data.rchild));printf("%-4d",data.n);
datadata)
/*中跟遍历左子树*/
/*中跟遍历右子树*/
/*后根遍历左子树*/
/*后根遍历右子树*/
voidWelcome()
{/*欢迎窗口*/
printf("\n\nWelcomeuseTraverseBinaryTree\n\n");
printf("\n\n\n\n");
printf("\n");
printf("Specialty:
InformationandComputationalScienceProgram\n");
printf(
Class:
2Grade:
2No.:
200530760214Name:
LinWeiyang\n"
Pressanykeytocontinue...\n");
);
getch();
voidMenu()
{/*菜单*/
***************************************************************
\n"
Pleaseselectthefunctionyouneed:
**\n"
**1.Createanothertree.
**2.PreordertraversetheBinaryTree.
**3.InordertraversetheBinaryTree.
**4.PostordertraversetheBinaryTree.
**5.DisplaytheBinaryTree.
printf("**6.Exit.
voidGoodbye()
{/*再见窗口
*/
"\n"
I!
TT
TTTTTTTTTT
TTTTTTTTTTT
TTTTTTTT
TTTTTTT
TTTTTTTTTTTTTTTTTTTT
TT\n
TTTTTTTTTTTTTTTTTTT
TT\n"
TTTTTT
"\n");
TTTTTTTTTTTTTTTTTTTTTTTT\n"
Copyright2010ZhangZhaohan\n"
printf(getch();
Pressanykeytoexit...\n"
voidmain(){inti;
Welcome();
Loop:
clrscr();
Menu();
switch(getch())
getch();gotoLoop;break;
case'6':
;break;
default:
gotoLoop;
Goodbye();
可执行文件:
程序运行截图:
运行窗口:
先根遍历
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1