北邮数据实验报告二叉树.docx
- 文档编号:3490958
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:27
- 大小:92.11KB
北邮数据实验报告二叉树.docx
《北邮数据实验报告二叉树.docx》由会员分享,可在线阅读,更多相关《北邮数据实验报告二叉树.docx(27页珍藏版)》请在冰豆网上搜索。
北邮数据实验报告二叉树
数据实验报告
实验名称:
院系:
学生姓名:
班级:
班内序号:
学号:
一、实验要求
掌握二叉树基本操作的实现方法
根据二叉树的抽象数据类型的定义,使用二叉链表实现一个二叉树。
二叉树的基本功能:
1、二叉树的建立
2、前序遍历二叉树
3、中序遍历二叉树
4、后序遍历二叉树
5、按层序遍历二叉树
6、求二叉树的深度
7、求指定结点到根的路径
8、二叉树的销毁
9、其他:
自定义操作
编写测试main()函数测试线性表的正确性
二、程序分析
2.1存储结构
1二叉树多采用二叉链表的存储结构。
二叉链表的每一个节点由三个域组成:
数据域,左指针域,右指针域。
2
在对二叉树的关键算法的实现过程中,采用了队列的存储结构。
队列的存储结构
示意图如图所示:
③
对于二叉树中每个结点的data域的赋值,我们事先把这些data储存在一个数组
中,通过对数组元素的调用事先对二叉树中每个结点的data域的赋值。
2.2关键算法分析
一:
二叉树的建立:
A.自然语言描述:
1首先判断调用的数组是否为空,如果为空,直接将一个已经初始化好的根节点置
为空。
2如果该数组不为空,则把调用的数组的第一个元素的赋给根节点的data域。
3采用递归的思想,分别将根节点的左右孩子作为根节点,递归调用该函数。
完成
对左右子树的赋值。
B.代码详细分析:
template
voidBiTree
:
Create(Node
{
if(buf[i-1]==0)
R=NULL;
else
{
R=newNode
R->data=buf[i-1];
Create(R->lch,buf,2*i);
Create(R->rch,buf,2*i+1);
}
}
二、前序遍历二叉树:
(非递归)
A.自然语言描述:
1:
建立栈
2:
判断该栈是否为空并且根节点是否为空指针
3:
如果根节点不是空指针,则输出它的data域,并且是它入栈
4:
入栈后将根节点指针指向它的左孩子
5:
如果根节点是空指针
6:
则根节点出栈,并且指向根节点的指针指向它的右孩子
B.代码详细分析:
template
:
Preorder(Node
{
Stack
while(!
S.IsEmpty()||(R!
=NULL))
{
if(R!
=NULL)
{
Print(R->data);
S.Push(R);
R=R->lch;
}
else
{
R=S.Pop();
R=R->rch;
}
}
}
三:
中序遍历二叉树:
(非递归)
A.自然语言描述:
1:
建立栈
2:
判断该栈是否为空并且根节点是否为空指针
3:
如果根节点不是空指针,将它入栈
4:
入栈后将根节点指针指向它的左孩子
5:
如果根节点是空指针
6:
则根节点出栈,输出该节点的data域,并且指向根节点的指针指向它的右孩子
B.代码详细分析:
template
:
Inorder(Node
{
Stack
while(!
S.IsEmpty()||(R!
=NULL))
{
if(R!
=NULL)
{
S.Push(R);
R=R->lch;
}
else
{
R=S.Pop();
Print(R->data);
R=R->rch;
}
}
}
四:
后序遍历二叉树:
(递归)
A.自然语言描述:
1:
判断根节点是否为空
2:
如果根节点不为空
3:
递归调用后续遍历函数,函数的参数改为根节点的左孩子
4:
递归调用后续遍历函数,函数的参数改为根节点的右孩子
5:
输出根节点的data域
B.代码详细分析:
template
:
Postorder(Node
{
if(R!
=NULL){
Postorder(R->lch);
Postorder(R->rch);
Print(R->data);
}
}
}
1
五:
层序遍历二叉树:
(递归)
A.自然语言描述:
1:
判断根节点是否为空
2:
如果根节点不为空
3:
输出根节点的data域
4:
递归调用层续遍历函数,函数的参数改为根节点的左孩子
5:
递归调用层序遍历函数,函数的参数改为跟结点的右孩子
B.代码详细分析:
template
:
Levelorder(Node
{
Queue
while(!
Q.IsEmpty()||(R!
=NULL))
{
if(R!
=NULL)
{
Print(R->data);
Q.EnQueue(R->lch);
Q.EnQueue(R->rch);
}
R=Q.DelQueue();
}
六:
求二叉树的深度:
(递归)
A.自然语言描述:
1:
判断根节点是否为空,如果根节点为空,返回0
2:
如果根节点不为空但是根节点的左右孩子同时为空,返回1
3:
如果以上两个条件都不成立
4:
递归调用求二叉树的深度,函数的参数改为根节点的左孩子,并且深度初始化
为1
5:
递归调用求二叉树的深度,函数的参数改为跟结点的右孩子,并且深度初始化
为0
6:
返回4与5步中得出深度较大的那个数作为二叉树的深度数
B.代码详细分析:
template
:
GetDepth(Node
{
if(R==NULL)returnd;
if((R->lch==NULL)&&(R->rch==NULL))
returnd+1;
else
{
intm=GetDepth(R->lch,d+1);
intn=GetDepth(R->rch,d+1);
returnn>m?
n:
m;
}
}
七:
二叉树的销毁:
(递归:
后续)
A.自然语言描述:
1:
判断根节点是否为空
2:
如果根节点不为空
3:
递归调用二叉树的销毁函数,参数改为根节点的左孩子
4:
递归调用二叉树的销毁函数,参数改为根节点的右孩子
5:
释放根节点指向的内存
B.代码详细分析:
template
:
Destroy(Node
{
if(R!
=NULL)
{
Destroy(R->lch);
Destroy(R->rch);
deleteR;
}
}
八:
求二叉树的叶子结点数:
(左+右+1)
A.自然语言描述:
1:
判断根节点是否为空,如果为空,返回0
2:
如果根节点不为空,切根节点的左右孩子同时为空,返回1
3:
递归调用求二叉树的叶子节点数函数,参数改为根节点的左孩子
4:
递归调用求二叉树的叶子结点数函数,参数改为根节点的右孩子
5:
返回根节点的左右子树的叶子结点数之和
B.代码详细分析:
template
:
LeafNodeCount(Node
{
if(R==NULL)return0;
if((R->lch==NULL)&&(R->rch==NULL))
return1;
else
{
intn=LeafNodeCount(R->lch);
intm=LeafNodeCount(R->rch);
returnm+n;
}
}
九:
求二叉树的结点数:
(左+右+1)
A.自然语言描述:
1:
判断根节点是否为空,如果为空,返回0
2:
如果根节点不为空
3:
递归调用求二叉树的结点数的函数,参数改为根节点的左孩子
4:
递归调用求二叉树的结点数的函数,参数改为根节点的右孩子
5:
返回根节点的左右字数的结点数之和
B.代码详细分析:
template
:
NodeCount(Node
{
if(R==NULL)return0;
else
{
intm=NodeCount(R->lch);
intn=NodeCount(R->rch);
returnm+n+1;
}
}
十、求指定结点到根的路径:
将s指针走过的路径存在数组Node
template
voidBiTree
:
Path(Node
{
Node
Node
inttag[10000];
inttop=0;
s=root;
do
{
while(s!
=NULL)
{
top++;
stack[top]=s;
tag[top]=0;
s=s->lch;
}
if(top>0)
{
if(tag[top]==1)
{
if(stack[top]->data==m)
{
cout<<"路径:
";
for(inti=top;i>=1;i--)
cout<
break;
}
top--;
}
else
{
s=stack[top];
if(top>0)
{
s=s->rch;
tag[top]=1;
}
}
}
}while(s!
=NULL||top!
=0);
}
2.3其他
对二叉树的操作上,前序遍历与中序遍历采用了非递归算法,后续遍历,层序遍历,求
二叉树深度,求二叉树叶子结点数,求二叉树结点数等函数采用了递归算法。
每一个操作都可以选择递归和非递归两种方法。
非递归算法可以提高运算的性能。
3.程序运行结果
主函数流程图如下:
程序运行结果截图:
4.总结
在本次试验中,我掌握了二叉树基本操作的实现方法。
在一系列操作中,既可以采用递归算法又可以采用非递归算法。
当然,不管是递归还是非递归算法,只要理解了运行的步骤,就可以。
这次试验非递归算法直接明了,运算性能好,但是程序代码多。
非递归算法代码少,但是不宜理解中间过程。
在本次试验中,又强化了我对递归算法的理解。
源代码:
fonction.h
#include
usingnamespacestd;
template
{
public:
Tdata;
Node
Node
intltag;
intrtag;
Node():
lch(NULL),rch(NULL),ltag(0),rtag(0){};//对这些变量赋初值
};
template
{
public:
Node
inttag;//
};
template
{
public:
Node
BiTree():
root(NULL){}
Node
voidCreate(Node
voidDestroy(Node
voidPrint(Te);//
~BiTree();//
//intSearch(Node
intLeafNodeCount(Node
intNodeCount(Node
intGetDepth(Node
Node
voidGetPath(Tx,Node
voidLevelorder(Node
voidPreorder(Node
voidInorder(Node
voidPostorder(Node
voidCreate(Node
voidPath(Node
};
template
{
public:
Stack():
Top(NULL){}//赋初值
intIsEmpty();//判断栈是否为空
TGetTop();//找top的data
voidPush(T);//把T放进栈中
TPop();//pop出去
~Stack();
protected:
structNode//
{
Tdata;
Node*next;
};
Node*Top;
};
template
{
public:
Queue();
intIsEmpty();//判断是否为空
voidEnQueue(T);//入队
TDelQueue();//删除元素
TGetFront();//获取front的data
~Queue();
Tdata;
protected:
structNode
{
Tdata;
Node*next;
};
Node*Front;
Node*Rear;
};
template
Node
:
Root()
{
returnroot;
}
//使用顺序结构存储的数据建立二叉链表树
template
voidBiTree
:
Create(Node
{
if(buf[i-1]==0)
R=NULL;
else
{
R=newNode
R->data=buf[i-1];
Create(R->lch,buf,2*i);//左孩子
Create(R->rch,buf,2*i+1);//右孩子
}
}
//销毁二叉树
template
:
Destroy(Node
{
if(R!
=NULL)
{
Destroy(R->lch);//后续删除
Destroy(R->rch);
deleteR;
}
}
template
:
Print(Te)
{
cout< } template : ~BiTree() { Destroy(root);//销毁二叉树的函数 } template voidBiTree : GetPath(Tx,Node { intf=0,r=0; boolw=false;// Queue if(R->data! =x) { if(w==false) Queue[++r].data=R->data; if(R->lch! =NULL)//前序遍历输出路径 GetPath(x,R->lch); if(R->rch! =NULL) GetPath(x,R->rch); if(w==true) { if(f! =r) cout< } else r--; } else { cout< for(intk=0;k<3;k++) { cout< } w=true; } }//查询树中的结点 /*template : Search(Node { if(R! =NULL) { if(R->data==e){p=R;return1;} if(Search(R->lch,e,p)) return1; else returnSearch(R->rch,e,p); } return0; } */ //求树的叶结点数 template : LeafNodeCount(Node { if(R==NULL)return0; if((R->lch==NULL)&&(R->rch==NULL)) return1; else { intn=LeafNodeCount(R->lch); intm=LeafNodeCount(R->rch); returnm+n; } } //求树的结点总数 template : NodeCount(Node { if(R==NULL)return0; else { intm=NodeCount(R->lch); intn=NodeCount(R->rch); returnm+n+1; } } //求树的深度 template : GetDepth(Node { if(R==NULL)returnd; if((R->lch==NULL)&&(R->rch==NULL)) returnd+1; else { intm=GetDepth(R->lch,d+1); intn=GetDepth(R->rch,d+1); returnn>m? n: m; } } //非递归先序遍历 template : Preorder(Node { Stack while(! S.IsEmpty()||(R! =NULL)) { if(R! =NULL) { Print(R->data); S.Push(R); R=R->lch; } else { R=S.Pop(); R=R->rch; } } } //非递归中序遍历 template : Inorder(Node { Stack while(! S.IsEmpty()||(R! =NULL)) { if(R! =NULL) { S.Push(R); R=R->lch; } else { R=S.Pop(); Print(R->data); R=R->rch; } } } //递归调用的后续遍历 template : Postorder(Node { if(R! =NULL){ Postorder(R->lch); Postorder(R->rch); Print(R->data); } } //层序遍历二叉树 template : Levelorder(Node { Queue while(! Q.IsEmpty()||(R! =NULL)) { if(R! =NULL) { Print(R->data); Q.EnQueue(R->lch); Q.EnQueue(R->rch); } R=Q.DelQueue(); } } template : IsEmpty() { if(Top==NULL)return1; elsereturn0; } template : GetTop() { if(Top==NULL)returnT(); elsereturnTop->data; } template : Push(Tt) { Node*s=newNode; s->data=t; s->next=Top; Top=s; } template TStack : Pop() { Tt; if(Top==NULL) cout<<"栈空,溢出"< else{
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据 实验 报告 二叉