实验一约瑟夫环问题.docx
《实验一约瑟夫环问题.docx》由会员分享,可在线阅读,更多相关《实验一约瑟夫环问题.docx(17页珍藏版)》请在冰豆网上搜索。
实验一约瑟夫环问题
实验报告部分
HUNANUNIVERSITY
课程实习报告
题目:
二叉树的实现
学生姓名赵庆磊
学生学号201508010525
专业班级计科1505
指导老师李晓鸿
完成日期2016.11.10
一、需求分析
(1)、建立一棵二叉树;
(2)、实现二叉树的四种遍历操作;
(3)、对储存的二叉树进行查找操作,并输出该节点的父节点,子节点(左孩子,右孩子)。
(4)、计算出二叉树的高度和节点数。
二、概要设计
抽象数据类型
二叉树是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的、分别称作这个根的左子树和右子树的二叉树组成。
所以可以用二叉链表来实现二叉树。
算法的基本思想
(1)、基于前序遍历的查找方式,并对其算法进行一些修改,然后将二叉树储存到链表中,
(2)、前序遍历,先访问节点,然后访问其子节点;
(3)、后序遍历,先访问节点的子节点(包括他们的子树),再访问该节点;
(4)、中序遍历,先访问左子节点(包括整棵子树),然后访问该节点,再访问右子节点(包括整棵子树);
(5)
程序的流程
程序由三个模块组成:
(1)输入模块:
完成对二叉树元素的输入,将输入结果储存在二叉链表中。
计算模块:
设计四个算法,链表中的元素作为参数,四个算法分别实现对二叉树的前序遍历,中序遍历,后序遍历,层序遍历等基本操作。
(2)输出模块:
屏幕上显示对二叉树遍历以后的结果,树的高度,节点数,要查找的节点的父节点,子节点。
三、详细设计
物理数据类型
二叉树除了根节点没有前驱和叶节点没有后继之外,其余节点均有一个前驱和一个以上的后继,所以二叉树不具有线性关系,就可以用二叉链(int型)表来实现二叉树的储存。
算法的具体步骤
通过构造函数创建一个二叉树,构造函数通过调用函数Create(BiNode*&R,Tdata[],inti,intn)创建二叉树,伪代码:
1.定义根指针,输入节点储存的data,若输入“#”,则该节点为空;
2.申请一个新节点,判断它的父结点是否不为空,如果不为空在判断其为左或者右孩子,并把地址付给父结点,把data写入。
voidBiTree:
:
Create(BiNode*&R,Tdata[],inti,intn){
if(i<=n){
R=newBiNode;
R->data=data[i-1];
Create(R->lch,data,2*i,n);
Create(R->rch,data,2*i+1,n);
}
elseR=NULL;
}
前序遍历
voidBiTree:
:
PreOrder(BiNode*R){
BiNode*S[100];
inttop=-1;
while((R!
=NULL)||(top!
=-1)){
if(R!
=NULL){
cout<data;
S[++top]=R;
R=R->lch;
}
else{
R=S[top--];
R=R->rch;
}
}
}
中序遍历伪代码;
1.设置递归边界条件:
ifroot==null则停止递归
2.递归遍历左子树
3.打印根节点数据域内
4.递归遍历右子
voidBiTree:
:
InOrder(BiNode*R){
if(R!
=NULL){
InOrder(R->lch);
cout<data;
InOrder(R->rch);
}
}
后序遍历伪代码:
1.设置递归边界条件:
ifroot==null则停止递归
2.递归遍历左子树
3.递归遍历右子树
4.访问根结点数据域
voidBiTree:
:
PostOrder(BiNode*R){
if(R!
=NULL){
PostOrder(R->lch);
PostOrder(R->rch);
cout<data;
}
}
层序遍历
1.队列Q及所需指针的定义和初始化
2.如果二叉树非空,将根指针入
3.循环直到队列Q为
voidBiTree:
:
LevelOrder(BiNode*R){
BiNode*queue[9];
intf=0,r=0;
if(R!
=NULL)
queue[++r]=R;while(f!
=r){
BiNode*p=queue[++f];
cout<data;
if(p->lch!
=NULL)
queue[++r]=p->lch;
if(p->rch!
=NULL)queue[++r]=p->rch;
}
}
算法的时空分析
前序遍历,时间复杂度O
(1)
中序遍历,时间复杂度O(n)
后序遍历,时间复杂度O(n)
层序遍历,时间复杂度O(n)
输入和输出的格式
输入
(1)、输入二叉树的根节点;
(2)、将二叉树的其余节点以前序遍历的形式输入;
(3)、输入一个数(0-3),为进行某一遍历算法的编号;
输出
(1)、树的高度;
(2)、数的节点数;
(3)、对二叉树遍历以后的结果;
(4)、对x节点进行查询;
(5)、存在于树中吗?
(YES或NO);
(6)、该节点的父节点;
(7)、该节点的左孩子;
(8)、该节点的右孩子;
四、调试分析
略。
五、测试结果
六、用户使用说明(可选)
七、实验心得(可选)
七、附录(可选)
#include
#include
#include
#include
usingnamespacestd;
typedefintElemType;//二叉树节点
classBTNode{//BinaryTreeNode
public:
ElemTypedata;
BTNode*lchild;//左孩子
BTNode*rchild;//右孩子
BTNode(ElemTyped,BTNode*left=NULL,BTNode*right=NULL):
data(d),lchild(left),rchild(right){}
};//二叉树
classBinaryTree{
private:
//根节点指针
BTNode*Root;//节点个数
intsize;
public:
//构造函数
BinaryTree();
BTNode*buildTree();//析构函数
~BinaryTree();//求树的高度
intheight();//获取节点个数
intgetSize()
{returnsize;}
voidgetHeight(BTNode*,int,int&);//指定遍历方式
voidtraverse();//前序遍历
voidpreOrder();
voidpreorder(BTNode*);//中序遍历
voidinOrder();
voidinorder(BTNode*);//后序遍历
voidpostOrder();
voidpostorder(BTNode*);//层次遍历
voidlevelOrder();//判断树是否为空
boolempty()
{returnRoot==NULL;}//获取根节点
BTNode*root()
{returnRoot;}//查找指定节点
boolfind(ElemType);//获取父节点
BTNode*parent(ElemType);//获取左孩子
BTNode*lchild(ElemType);//获取右孩子
BTNode*rchild(ElemType);
};//类实现
//构造函数
BinaryTree:
:
BinaryTree(){
size=0;
cout<<"输入根节点";
Root=buildTree();
}
BTNode*BinaryTree:
:
buildTree(){
ElemTypedata;
BTNode*p=NULL;
cin>>data;//输入0结束
if(data==0)
returnp;
else{
p=newBTNode(data);
size++;
if(!
p){
cerr<<"内存分配失败!
"<exit(0);
}
else{
cout<<"请输入"<p->lchild=buildTree();
cout<<"请输入"<p->rchild=buildTree();
}
}
returnp;
}
//析构函数
BinaryTree:
:
~BinaryTree(){
queueq;
q.push(Root);
BTNode*p=NULL;
while(!
q.empty()){
p=q.front();
q.pop();//左孩子不为空,则左孩子入队
if(p->lchild)
q.push(p->lchild);//右孩子不为空,则右孩子入队
if(p->rchild)
q.push(p->rchild);//释放内存
deletep;
}
}//求树的高度
intBinaryTree:
:
height(){
if(empty())
return0;
inth=0;
getHeight(Root,0,h);
returnh;
}
voidBinaryTree:
:
getHeight(BTNode*p,intlevel,int&h){
if(p){
if(level>h)
h=level;
getHeight(p->lchild,level+1,h);
getHeight(p->rchild,level+1,h);
}
}
//指定遍历方式
voidBinaryTree:
:
traverse(){
intchoice;
cout<<"输入遍历方式:
0(前序)、1(中序)、2(后序)、3(层次):
";
cin>>choice;
while(choice<0||choice>3){
cout<<"输的不对!
请重新输入:
";
cin>>choice;
}
switch(choice){
case0:
preOrder();break;
case1:
inOrder();break;
case2:
postOrder();break;
case3:
levelOrder();break;
}
}
//前序遍历:
根->左->右
voidBinaryTree:
:
preOrder(){
BTNode*pnode=Root;
preorder(pnode);
cout<}
voidBinaryTree:
:
preorder(BTNode*p){
if(p){
cout<data;
preorder(p->lchild);
preorder(p->rchild);
}
}
//中序遍历:
左->根->右
voidBinaryTree:
:
inOrder(){
BTNode*pnode=Root;
inorder(pnode);
cout<}
voidBinaryTree:
:
inorder(BTNode*p){
if(p)
{
inorder(p->lchild);
cout<data;
inorder(p->rchild);
}
}
//后序遍历:
左->右->根
voidBinaryTree:
:
postOrder(){
BTNode*pnode=Root;
postorder(pnode);
cout<}
voidBinaryTree:
:
postorder(BTNode*p){
if(p){
postorder(p->lchild);
postorder(p->rchild);
cout<data;
}
}
//层次遍历
voidBinaryTree:
:
levelOrder(){//使用STL中的队列
queueq;//根节点入队
q.push(Root);
BTNode*p=NULL;
while(!
q.empty()){
p=q.front();//打印
cout<data;
q.pop();//左孩子不为空,则左孩子入队
if(p->lchild)
q.push(p->lchild);//右孩子不为空,则右孩子入队
if(p->rchild)
q.push(p->rchild);
}
cout<}
//查找指定节点
boolBinaryTree:
:
find(ElemTypedata){
if(!
empty()){
//按层次遍历查找
queueq;
q.push(Root);
BTNode*p=NULL;
while(!
q.empty()){
p=q.front();//比较
if(p->data==data)
returntrue;
q.pop();
if(p->lchild)
q.push(p->lchild);
if(p->rchild)
q.push(p->rchild);
}
}//在树空和不存在该节点的情况下,都返回false
returnfalse;
}
//获取父节点
BTNode*BinaryTree:
:
parent(ElemTypedata){
if(!
empty()){//根节点的父节点为空
if(Root->data==data)
returnNULL;
stacks;
BTNode*p=Root;
while(!
s.empty()||p){
if(p){
if((p->lchild&&p->lchild->data==data)||(p->rchild&&p->rchild->data==data))
returnp;
s.push(p);
p=p->lchild;
}
else{//左子树访问完后,访问右子树
p=s.top();
s.pop();
p=p->rchild;
}
}
}
returnNULL;
}
//获取左孩子
BTNode*BinaryTree:
:
lchild(ElemTypedata){
if(!
empty()){//按层次遍历查找
queueq;
q.push(Root);
BTNode*p=NULL;
while(!
q.empty()){
p=q.front();//比较
if(p->data==data)
returnp->lchild;
q.pop();
if(p->lchild)
q.push(p->lchild);
if(p->rchild)
q.push(p->rchild);
}
}
returnNULL;//在树空和不存在该节点的情况下,都返回NULL
}
//获取右孩子
BTNode*BinaryTree:
:
rchild(ElemTypedata){
if(!
empty()){//按层次遍历查找
queueq;
q.push(Root);
BTNode*p=NULL;
while(!
q.empty()){
p=q.front();//比较
if(p->data==data)
returnp->rchild;
q.pop();
if(p->lchild)
q.push(p->lchild);
if(p->rchild)
q.push(p->rchild);
}
}
returnNULL;//在树空和不存在该节点的情况下,都返回NULL
}
intmain(){
cout<<"******二叉树******"<BinaryTreetree;
cout<<"树的高度是"<cout<<"树中共有节点个数"<tree.traverse();
ElemTypedata=2;
cout<<"对节点"<cout<<"存在于树中吗?
";
tree.find(data)?
cout<<"Yes!
"<cout<<"No!
"<BTNode*p=NULL;
p=tree.parent(data);
p?
cout<<"父节点是"<data<cout<p=tree.lchild(data);
p?
cout<<"左孩子是"<data<cout<<"无左孩子!
"<p=tree.rchild(data);
p?
cout<<"右孩子是"<data<cout<<"无右孩子!
"<system("pause");
return0;
}