二叉排序树实验报告材料.docx
- 文档编号:25416836
- 上传时间:2023-06-08
- 格式:DOCX
- 页数:24
- 大小:74.56KB
二叉排序树实验报告材料.docx
《二叉排序树实验报告材料.docx》由会员分享,可在线阅读,更多相关《二叉排序树实验报告材料.docx(24页珍藏版)》请在冰豆网上搜索。
二叉排序树实验报告材料
二叉排序树的实现
一、实验内容与要求
1)实现二叉排序树,包括生成、插入,删除;
2)对二叉排序树进行先根、中根、和后根非递归遍历;
3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。
二、实验方案
1.选择链表的方式来构造节点,存储二叉排序树的节点。
//树的结构
structBSTNode
{
//定义左右孩子指针
structBSTNode*lchild,*rchild;
//节点的关键字
TElemTypekey;
};
intdepth=0;
//定义一个structBSTNode类型的指针
typedefBSTNode*Tree;
2.对树的操作有如下方法:
//创建二叉排序树
TreeCreatTree(TreeT);
//二叉树的深度,返回一个int值为该树的深度
intTreeDepth(TreeT)
//树状输出二叉树,竖向输出
voidPrintTree(TreeT,intlayer);
//查找关键字,如果关键字存在则返回所在节点的父节点,如果关键字不存在则返回叶子所在的节点
StatusSearchBST(TreeT,TElemTypekey,Treef,Tree&p);
//向树中插入节点
StatusInsertBST(Tree&T,TElemTypee);
//删除节点
StatusDelete(Tree&T);
//删除指定节点,调用Delete(Tree&T)方法
StatusDeleteData(Tree&T,TElemTypekey);
//非递归先序遍历
voidx_print(TreeT);
//非递归中序遍历
Voidz_print(TreeT);
//非递归后序遍历
voidh_print(TreeT);
3.对二叉排序树非递归先根、中根、后根遍历,采用栈来存储一次遍历过的节点的形式来辅助实现
//自定义类型以SElemType作为栈中指针返回的值的类型
//也就是要返回一个节点的指针
typedefTreeSElemType;
//栈的结构
structStack
{
//栈底指针
SElemType*base;
//栈顶指针
SElemType*top;
//栈的容量
intstacksize;
};
4.栈的操作方法:
//创建一个空栈
StatusInitStack(Stack&S);
//获取栈顶元素并删除栈中该位置的元素
SElemTypePop(Stack&S,SElemType&elem)
//获取栈顶元素返回栈顶元素不对栈做任何修改
SElemTypegetTop(StackS,SElemType&elem)
//删除栈顶元素
StatusDeleteTop(Stack&S)
//往栈中压入数据
StatusPush(Stack&S,SElemTypeelem)
//判断栈是否为空
StatusIsEmpty(StackS)
三、代码实现
#include
#include
usingnamespacestd;
//定义宏
#defineOK1
#defineERROR0
#defineSTACK_INIT_SIZE10
#defineSTACK_INCREMENT2
//定义宏分别为栈的初始容量和栈的增加容量
#defineSTACK_INIT_SIZE10
#defineSTACK_INCREMENT2
typedefintTElemType;
//树的结构
structBSTNode
{
//定义左右孩子指针
structBSTNode*lchild,*rchild;
//节点的关键字
TElemTypekey;
};
intdepth=0;
//定义一个structBSTNode类型的指针
typedefBSTNode*Tree;
//自定义类型以SElemType作为栈中指针返回的值的类型
//也就是要返回一个节点的指针
typedefTreeSElemType;
//栈的结构
structStack
{
//栈底指针
SElemType*base;
//栈顶指针
SElemType*top;
//栈的容量
intstacksize;
};
//自定义类型
typedefintStatus;
//创建一个空栈
StatusInitStack(Stack&S)
{
//给栈指针分配空间
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
//如果分配空间失败则退出
if(!
S.base)
exit(OVERFLOW);
//栈底、栈顶指针相等表示栈为空
//S.base=S.top;
//此句代码若以如上句格式则在执行时会出现内存非法访问的错误
S.top=S.base;
//初始化栈的容量
S.stacksize=STACK_INIT_SIZE;
returnOK;
}
//获取栈顶元素并删除栈中该位置的元素
SElemTypePop(Stack&S,SElemType&elem)
{
if(S.top==S.base)
{
cout<<"gaizhanyijingweikong"< returnERROR; } else { elem=*--S.top; } returnelem; } //获取栈顶元素返回栈顶元素不对栈做任何修改 SElemTypegetTop(StackS,SElemType&elem) { //如果为空栈则返回ERROR if(S.base==S.top) { cout<<"gaizhanyijingweikong"< returnERROR; } //如果栈不为空则返回栈顶元素 else { elem=*(S.top-1); } returnelem; } //删除栈顶元素 StatusDeleteTop(Stack&S) { //判断栈是否为空 if(S.base==S.top) { cout<<"gaizhanyijingweikong"< returnERROR; } //如果栈不为空则删除栈顶元素 else { --S.top; } returnOK; } //往栈中压入数据 StatusPush(Stack&S,SElemTypeelem) { //如果栈的容量超过初始化容量则增加栈的容量 if(S.top-S.base>=S.stacksize) { S.base=(SElemType*)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(SElemType)); if(! S.base) exit(OVERFLOW); S.top=S.base+S.stacksize; S.stacksize+=STACK_INCREMENT; } //添加数据 *S.top++=elem; returnOK; } //判断栈是否为空 StatusIsEmpty(StackS) { if(S.base==S.top) returnOK; else returnERROR; } /////////////////////////////////////////////////////////////////// ///////////以下的代码主要是对树的操作///////////////////////////// /////////////////////////////////////////////////////////////////// //创建空树 StatusInitTree(Tree&T) { T=NULL; returnOK; } //查找关键字 //如果关键字存在则返回所在节点的父节点 //如果关键字不存在则返回叶子所在的节点 StatusSearchBST(TreeT,TElemTypekey,Treef,Tree&p) { if(! T) { p=f; returnERROR; } elseif(T->key==key) { p=T; returnOK; }elseif(T->key>key) returnSearchBST(T->lchild,key,T,p); elseif(T->key returnSearchBST(T->rchild,key,T,p); } //向树中插入节点 StatusInsertBST(Tree&T,TElemTypee) { Treep; if(! SearchBST(T,e,NULL,p)) { Trees=(Tree)malloc(sizeof(BSTNode)); s->key=e; s->lchild=s->rchild=NULL; if(! p) { T=s; }elseif(p->key>e) { p->lchild=s; }elseif(p->key { p->rchild=s; } } else returnERROR; } //创建二叉排序树 TreeCreatTree(TreeT) { TElemTypeelem; cout<<"请输入数据,以0结束输入操作"< cin>>elem; while(elem! =0&&elem>0) { intk=InsertBST(T,elem); if(k) { cout<<"请输入数据,以0结束输入操作"< cin>>elem; } else { cout<<"插入错误或存在重复元素"< //异常退出 returnERROR; } } returnT; } //删除节点 StatusDelete(Tree&T) { Treep,q; if(T->lchild! =NULL&&T->rchild! =NULL) { p=T; q=T->lchild; T=q; while(q->rchild! =NULL) { q=q->rchild; } q->rchild=p->rchild; free(p); returnOK; } if(T->rchild==NULL&&T->lchild! =NULL) { p=T; T=T->lchild; free(p); returnOK; } elseif(T->lchild==NULL&&T->rchild! =NULL) { p=T; T=T->rchild; free(p); returnOK; } elseif(T->rchild==NULL&&T->lchild==NULL) { T=NULL; free(T); returnOK; } } //删除指定节点 StatusDeleteData(Tree&T,TElemTypekey) { if(! T) { cout<<"找不到要删除的元素,请重新选择! "< returnERROR; } if(T->key==key) { Delete(T); } elseif(T->key>key) DeleteData(T->lchild,key); elseif(T->key DeleteData(T->rchild,key); returnOK; } //先序遍历 voidx_print(TreeT) { //Treef; StackS; InitStack(S); if(T==NULL) { cout<<"树为空"< } while(T! =NULL||! IsEmpty(S)) { if(T! =NULL) { cout< Push(S,T); T=T->lchild; } else { Pop(S,T); T=T->rchild; } } } //z中序遍历 voidz_print(TreeT) { //Treef; StackS; InitStack(S); if(T==NULL) { cout<<"树为空"< } while(T! =NULL||! IsEmpty(S)) { if(T! =NULL) { Push(S,T); T=T->lchild; } else { Pop(S,T); cout< T=T->rchild; } } } //后序遍历 voidh_print(TreeT) { StackS; InitStack(S); Treef=NULL; if(T==NULL) { cout<<"树为空"< } while(T! =NULL||! IsEmpty(S)) { while(T! =NULL) { Push(S,T); T=T->lchild; } getTop(S,T); if(T->rchild==NULL||T->rchild==f) { cout< Pop(S,f); T=NULL; } else { T=T->rchild; } } } //二叉树的深度 intTreeDepth(TreeT) { intleft,right,max; if(T! =NULL) { left=TreeDepth(T->lchild); right=TreeDepth(T->rchild); max=left>right? left: right; returnmax+1; }else { returnERROR; } } //竖向输出 //树状输出二叉树 voidPrintTree(TreeT,intlayer) { intk; if(T==NULL) return; PrintTree(T->rchild,layer+1); for(k=0;k cout<<""; cout< PrintTree(T->lchild,layer+1); } voidmain() { intkey; inth; Treetree; InitTree(tree); tree=CreatTree(tree); h=TreeDepth(tree); cout<<"树状输出为: "< PrintTree(tree,h); if(! tree) { exit(-1); } cout<<"\n\n---------------请输入你要选择的操作--------------------\n"< cout<<"a.删除二叉树中的元素b.向二叉树中添加元素"< cout<<"c.先根遍历二叉树d.中根遍历二叉树"< cout<<"e.后根遍历二叉树o.退出操作"< cout<<"\n\n------------------------------------------------------\n"< //intkey; charselect; cin>>select; while(select! ='o') { switch(select) { case'o': exit(0); break; case'a': if(! tree) { cout<<"树以为空,请重新选择操作! "< cin>>select; } else{ cout<<"请输入要删除的元素"< cin>>key; DeleteData(tree,key); cout<<"树状输出为: "< PrintTree(tree,h); } break; case'b': cout<<"请输入要插入的元素"< cin>>key; InsertBST(tree,key); cout<<"树状输出为: "< PrintTree(tree,h); break; case'c': cout<<"先根遍历结果为: "< x_print(tree); cout< break; case'd': cout<<"中根遍历结果为: "< z_print(tree); cout< break; case'e': cout<<"后根遍历结果为: "< h_print(tree); cout< break; default: cout<<"输入错误"< exit(-1); break; } cout<<"---------------请输入你要选择的操作--------------------"< cout<<"a.删除二叉树中的元素b.向二叉树中添加元素"< cout<<"c.先根遍历二叉树d.中根遍历二叉树"< cout<<"e.后根遍历二叉树o.退出操作"< cout<<"--------------------------------------------------------"< cin>>select; } } 四、实验结果和数据处理 输入数据同选择操作结果如上图所示 操作现象: 输入操作的时候如果输入的不是数值(比如字母)就会出现插入操作错误的提示,然后异常退出操作;或者当输入的关键字已在树中存在,也会提示“重复输入”然后异常退出(这点存在不足,应该修改为提示之后重新输入操作) 删除现象: 如果要删除的关键字不存在则会提示不存在该关键字然后重新输入,如果树为空则会提示树为空并重新选择操作 遍历现象: 如果树为空,则不会退出操作,而是提示“树为空”。 选择操作: 如果不是按要求输入字符a,b,c,d,e,o则会提示输入错误并异常退出; 注: 对于树的一些删除、增加、遍历操作的详细文字解释省略。 参考文献: 《数据结构》算法实现及解析西安电子科技大学出版社出版严蔚敏吴伟民编著 《数据结构(c语言版)》清华大学出版社严蔚敏吴伟民编著
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 二叉排序树 实验 报告 材料