树的应用.docx
- 文档编号:24226490
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:39
- 大小:608.63KB
树的应用.docx
《树的应用.docx》由会员分享,可在线阅读,更多相关《树的应用.docx(39页珍藏版)》请在冰豆网上搜索。
树的应用
软件综合课程设计
树的应用
宿舍管理查询软件
二〇一四年六月
树的应用
1.问题陈述
树与二叉树的转换的实现,以及树的前序、后序的递归、非递归算法,层次序的非递归算法的实现,应包含建树的实现。
(1)程序内容包括
①创建二叉树
②前序遍历递归算法
③后序遍历递归算法
④前序非递归遍历算法
⑤后序非递归遍历算法
⑥层序非递归遍历算法
⑦树与二叉树的转换
⑧输出树
⑨退出操作
(2)详细步骤
二叉树创建
用链表创建一个树节点的结构体,从键盘输入数据,存入数组。
把下标为2*i+1的值存入左孩子,把下标为2*i+2的存入右孩子btreenode creat(),btreenode stree_creat(char*a,int) 。
二叉树前序递归算法
若二叉树为空,则操作空;否则①访问根节点;②先序遍历左子树 ③先序遍历右子树。
Viod preorder(btreenode root)
二叉树后序遍历递归算法
若二叉树为空,则操作空;否则①后序遍历左子树;②后序遍历右子树;③访问根节点;void postorder(btreenode root) .
前序非递归遍历算法
Btreenode根指针,若btreenode!
=NULL对于非递归算法引入栈模拟递归工作栈,初始时栈为空。
Void F_preorder(btreenode root)
后序非递归遍历算法
Btreenode是要遍历树的根指针,后续遍历要求在遍历完左右子树之后,再访问根。
需要判断根节点的左右子树是否都遍历过,void F_postorder(btreenode root)
层次遍历递归算法
从左到右访问树的节点,层序遍历用于保存节点的容器是队列。
Void levelorder(btreenode root)
树与二叉树的转换算法
转换时节点的第一个孩子变为它的左孩子,兄弟节点变为它的右孩子。
Void exchange(),class tree
2.程序代码
#include
usingnamespacestd;
#include
#include
#definemaxsize100
constintk=10;//=========================
#defineLENsizeof(structbtree)
intmax=1;
typedefstructbtree//二叉树节点结构体
{
btree*lchild,*rchild;chardata;
}*btreenode;
structtree//=====================================
{
chardate;
tree*a[k];
};
typedefstructstackelemtype//栈的结构体
{
btreenodeptr;
intflag;
}stackelemtype;
btreenodep;
tree*q;
//二叉树的建立
btreenodestree_creat(char*a,intk)
{
btreenoderoot;
max++;
if(a[k]=='\0'||k>maxsize)
returnNULL;//判断树是否为空
else{
root=(btreenode)malloc(LEN);//动态申请节点
root->data=a[k];
root->lchild=stree_creat(a,2*k+1);//递归调用为左孩子赋值
root->rchild=stree_creat(a,2*k+2);//递归调用为右孩子赋值
returnroot;//返回根节点指针
}
}
voidprint(btreenoderoot)//输出所创建的二叉树
{
btreenodeh[maxsize]={NULL};
inttop=0,base=0,j=0,k=0,n=0,m=0;
h[top]=root;
j=log(max+1)/log
(2)-1;
if(pow(2,j+1)-1 cout<<"你刚输入的: \n"; while(h[base]! =NULL)//把二叉树的值一次输入数组 { h[++top]=h[base]->lchild; h[++top]=h[base]->rchild; base++; } for(top=0;h[k]! =NULL;top++)//按层输出 { m=pow(2,j)-top;//计算每行输出的空格数 if(top! =0)m=m-top; for(n=0;n cout<<""; for(base=0;base =NULL;base++)//控制每层输出的个数 { if(h[k]->data=='0')cout<<"["<<"]";//当为空时输出[] elsecout< k++; } cout<<"\n"; for(n=0;n<(m-1);n++) cout<<""; for(base=0;base =NULL;base++) cout<<"/"<<"|"; cout<<"\n"; } } //二叉树的后续遍历递归算法 voidpostorder(btreenoderoot) { if(root==NULL)return;//递归调用的约束条件 else { postorder(root->lchild); postorder(root->rchild); if(root->data=='0'); else cout<<"["< } } //二叉树的前序遍历递归算法 voidpreorder(btreenoderoot) { if(root==NULL)return;//递归调用的约束条件 else { if(root->data=='0'); else cout<<"["< preorder(root->lchild); preorder(root->rchild); } } //二叉树的前序遍历非递归算法 voidF_preorder(btreenoderoot) { btreenodes[maxsize];//申请一个btreenode数组 inttop=0;//采用顺序栈,并假定不会发生上溢 do{ while(root! =NULL)//当结点不为空时 { if(root->data=='0'); else cout<<"["< s[++top]=root;//依次将接点压入栈 root=root->lchild;//跟赋值为它的左孩子 } if(top>0)//节点为空但栈顶不为零时 { root=s[top--];//栈顶下移把栈顶元素赋给根节点 root=root->rchild;//跟赋值它为右孩子 } } while(root! =NULL||top>0); } //二叉树的后序遍历非递归算法 voidF_postreorder(btreenoderoot) { stackelemtypes[maxsize]; btreenodep=root; inttop=0; do{ while(p! =NULL)//当结点不为空时 { s[top].flag=0;//标记位赋为零 s[top].ptr=p;//将树的节点依次压入栈中 p=p->lchild;//树沿左子树下移 top++; } while(s[top-1].flag==1)//当栈的做上面元素标记为一时输出 { if(s[top-1].ptr->data=='0')top--; else cout<<"["< } if(top>0)//当节点为空但栈顶不为零时 { s[top-1].flag=1;//栈的最上面元素标记位赋值为一 p=s[top-1].ptr;//栈的最上面元素树节点赋给p p=p->rchild;//树沿右子树下移 } }while(top>0); } //层次遍历 voidlevelorder(btreenoderoot) { btreenodes[maxsize];//申请一个btreenode数组 intmax,i=0; s[0]=root;//数组首元赋为根节点 while(root! =NULL)//当节点不为空时 { s[2*i+1]=root->lchild;//左孩子赋给下标为2*i+1的数组元 s[2*i+2]=root->rchild;//右孩子赋给下标为2*i+2的数组元 i++; root=s[i];//root变为当前数组元素的值 max=i; } for(i=0;i { if(s[i]->data=='0'); else cout<<"["< } } voidpause() { cout< system("pause"); cout< } //树转换成二叉树 voidexchange(tree*&H,btree*BH)//============================== { H=newtree; for(inti=0;i { H->a[i]=NULL; } if(BH==NULL) { H=NULL; } else { H->date=BH->data; if(BH->lchild! =NULL) { exchange(H->a[0],BH->lchild); intj=1; btree*c=BH->lchild; while(c->rchild! =NULL) { c=c->rchild; exchange(H->a[j],c); j++; } } } } voidprinttree(tree*H) { if(H! =NULL) { cout<<"\t"<<""< for(inti=0;i { printtree(H->a[i]); } } } btreenodecreat() { btreenodep=NULL; cout<<"请输入你的二叉树(按层次由上往下从左到右依次输入并按#结束,如果节点为空请输入'0'),输入为: \n"; inti=0,j=0; charb[maxsize]={'#'},n;//当输入'#'时给数组赋值 do{ cin>>n; if(n! ='#')b[i]=n; i++; }while(n! ='#'); p=stree_creat(b,0);//创建树 print(p);//输出树 returnp; } //主函数 intmain() { intk; cout<<"\n"; cout<<"\n__________________________________________"; cout<<"|欢迎使用多种遍历器|"; cout<<"|树与二叉树的转换|"; cout<<"||"; cout<<"|___________________________________________|\n"; do{ cout<<"\n"; cout<<"\n1.创建二叉树"; cout<<"\n2.前序遍历递归算法"; cout<<"\n3.后序遍历递归算法"; cout<<"\n4.前序非递归遍历算法"; cout<<"\n5.后序非递归遍历算法"; cout<<"\n6.层序非递归遍历算法"; cout<<"\n7.树与二叉树的转换并输出树"; cout<<"\n8.退出操作\n"; cout<<"请选择你要进行的操作(数字键): "; cin>>k; switch(k) { case1: {p=creat();//调用creat()创建二叉树 }break; case2: { cout<<"二叉树的前序递归遍历: "; preorder(p);//调用preorder()前序遍历 }break; case3: { cout<<"二叉树的后序递归遍历: "; postorder(p);//调用postorder()后续遍历 }break; case4: { cout<<"二叉树的前序非递归遍历: "; F_preorder(p);//调用F_preorder(p)前序遍历 }break; case5: { cout<<"二叉树的后序非递归遍历: "; F_postreorder(p);//调用F_postorder(p)后序遍历 }break; case6: { cout<<"二叉树的层次非递归递归遍历: "; levelorder(p); }break; case7: { btree*a; a=newbtree; a->data=0; a->lchild=p; a->rchild=NULL; exchange(q,a);//调用exchange()实现树与二叉树的转换 deletep; printtree(q); }break; } }while(k>=0&&k<8);return0; } 3.运行结果 菜单显示界面: 创建二叉树界面: 前序、后序遍历递归算法界面: 前序、后序、层次序非递归遍历算法界面: 树与二叉树的转换并输出树、退出操作等: 4.设计体会与总结 通过这次课程设计,对我的逻辑思维能力是一个很大的锻炼。 同时,在编程方面,我开始从整体的角度来考虑问题了,而不再像以前一样的,胡乱动手。 也就是因为先前的这种编程习惯,使得我在课程设计过程中浪费了不少的时间,尝到了教训。 从本次的实验中,我加强了对以往学习的知识的巩固,如栈、链表等。 培养了解决实际问题的编程能力。 根据数据对象的特性,学会了数据组织的方法,把现实世界中的实际问题在计算机内部表示出来。 培养了基本的、良好的程序设计技能。 同时体会到算法的高效性永远是程序设计的难点和重点,只有高效的算法才能更好更快的得到满意的答案 此外,通过这些天的程序及报告的编写,我也发现了自己的很多不足,知识的很多漏洞,看到了自己的实践经验还是比较缺乏,理论联系实际的能力还是比较脆弱。 尤其是编写程序所要拥有的知识和技能比较缺乏。 程序编好了,还要经过调试和修改,这步也很关键,好的程序是经过了无数次的修改和调试才产生的。 我的程序基本上能够满足要求,但还有一些地方需要改进,在今后我应该在多看书的同时还要加强实践的练习。 才能进一步提高自己的编程能力。 宿舍管理查询软件 1.问题陈述 1)任务: 为宿舍管理人员编写一个宿舍管理查询软件,程序设计要求: A.采用交互工作方式 B.建立数据文件,数据文件按关键字(姓名、学号、房号)进行排序(冒泡、选择、插入排序等任选一种) 2)查询功能: (用二分查找实现以下操作) A.按姓名查询 B.按学号查询 C.按房号查询 3)打印任一查询结果(可以连续操作) 2.需求分析 由分析可知,该宿舍管理系统必须满足用户以下基本需求: <1>可对入住学生可进行信息录入并显示;<2>可以显示排序后的学生信息 <3>可按学号,姓名,房间号等任意一种方式查询学生的信息 3.概要设计 该程序的由多种函数实现,每个函数具有不同的功能,主要有主菜单函数,插入功能子菜单函数,查找功能子菜单函数,学生信息录入函数,显示函数,排序函数以及查找函数。 在每个区域中会调用不同的函数来实现主要的功能。 比如,在学生显示这个功能里调用显示函数;在显示信息时调用排序函数先对需要输出的信心进行排序,然后再输出;在查找功能里会调用查找函数来进行查找,包括按照性别,学号,姓名,房间号等查询。 而最主要的函数有 <2>排序函数,用快速排序函数来实现; <3>查找函数,用逐个查找法; 4.详细设计 根据用户需求不同,将系统划分了不同的功能模块,而依据不同的功能模块编写不同的程序模块,具体如下: <1>信息录入模块(即为程序中的shuru()函数) /*自定义输入函数*/ structstudentshuru() { structstudentstu; cout<<"学号: "; cin>>stu.ID; cout<<"姓名: "; cin>>stu.name; cout<<"性别(g/b): "; fflush(stdin); cin>>stu.sex; cout<<"房间号: "; cin>>stu.roomnum; cout<<"是否继续? (Y/N)"< returnstu; } <2>信息查询模块(即为程序中的chazhao()函数,包括按学号chazaho1(),按姓名chazaho2(),按房间号chazaho3()三个子函数) /*自定义按照学号查找函数*/ voidchazhao1(structstudentstu[N],inti) { intselect,j; charch; cout<<"*******************您选择的是按照学号查找*******************\n"; do { cout<<"\n请输入学号: "; cin>>select; for(j=0;j { if(select==stu[j].ID) {break;} } if(j { cout<<"\n\t*********************************************************\n"; cout<<"\t学号\t姓名\t性别\t房间号\t\n"; cout<<"\t*********************************************************\n"; display(stu[j]); } else { cout<<"你查找的信息不存在\n"; } }while(ch=='y'); fflush(stdin); ch=getchar(); } /*自定义按照姓名查找函数*/ voidchazhao2(structstudentstu[N],inti) { intj; charname[15]; charch; cout<<"*******************您选择的是按照姓名查找*******************\n"; do { cout<<"\n请输入姓名: "; cin>>name; for(j=0;j { if(strcmp(name,stu[j].name)==0) {break;} } if(j { cout<<"\n\t*********************************************************\n"; cout<<"\t学号\t姓名\t性别\t房间号\t\n"; cout<<"\t*********************************************************\n"; display(stu[j]); } else { cout<<"你查找的信息不存在\n"; } fflush(stdin); ch=getchar(); }while(ch=='y'); } //按照房间号查找 voidchazhao3(structstudentstu[N],inti) { intj,room; charch; cout<<"*******************您选择的是按照房间号查找*******************\n"; do { cout<<"\n\n请输入房间号: "; cin>>room; for(j=0;j { if(room==stu[j].roomnum) {break;} } if(j { cout<<"\n\t*********************************************************\n"; cout<<"\t学号\t姓名\t性别\t房间号\t\n"; cout<<"\t*********************************************************\n"; display(stu[j]);data<<"]";data<<"]";//依次输出
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 应用