数据结构作业二叉树修改版文档格式.docx
《数据结构作业二叉树修改版文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构作业二叉树修改版文档格式.docx(25页珍藏版)》请在冰豆网上搜索。
![数据结构作业二叉树修改版文档格式.docx](https://file1.bdocx.com/fileroot1/2022-11/22/4ee52496-c453-4878-9af7-be4e235ae4a6/4ee52496-c453-4878-9af7-be4e235ae4a61.gif)
rchild=Creat();
//递归建立右子树
}returnroot;
}构造这样的函数,可以在输入时,按先序遍历顺序每次输入一个节点的数据,可以实现任意二叉树的构造。
为了检验构造的二叉树是否为预先设想的二叉树,需要遍历二叉树并进行输出。
考虑到单一的输出并不能确定唯一的二叉树,因此对遍历二叉树的四种常用发方法,即先序遍历,中序遍历,后续遍历,层次遍历分别实现,通过遍历结果检验构造的二叉树是否为预先设计好的二叉树。
先序遍历:
采用递归的方法建立。
templatevoidBiTree:
xianxu(BiNode*root){if(root==NULL)return;
//如果节点为空,则返回空else{coutdata
xianxu(root->
lchild);
//先序遍历树的左子树xianxu(root->
rchild);
//先序遍历树的右子树
}中序遍历:
递归方法建立:
zhongxu(BiNode*root){
if(root==NULL)return;
//如果节点为空,则返回空else{zhongxu(root->
//中序递归遍历root的左子树coutdata
//访问根结点
zhongxu(root->
//中序递归遍历root的右子树
}
}后序遍历:
houxu(BiNode*root){
if(root==NULL)
return;
//如果节点为空,返回空else{houxu(root->
//后序递归遍历root的左子树houxu(root->
//后序递归遍历root的右子树coutdata
//访问根节点
}}层序遍历:
采用非递归方法。
利用队列的方法层序遍历二叉树。
建立一个队列,在访问一个节点的时候,把它的左孩子和右孩子入队,并且将这个节点出队。
当队列为空时,就完成了对二叉树的层序遍历。
templatevoidBiTree:
cengxu(BiNode*root){constintMaxSize=100;
intfront=0;
intrear=0;
//利用队列的方法对树进行层序遍历BiNode*Q[MaxSize];
BiNode*q;
if(root==NULL)return;
//如果节点为空,返回空else{
Q[rear++]=root;
//若节点不为空,则该节点入队while(front!
=rear)
{
q=Q[front++];
//只要队列不为空,则节点依次出队coutdata
if(q->
lchild!
=NULL)
Q[rear++]=q->
lchild;
rchild!
rchild;
//同时,该节点的双子入队
}}}函数主体部分:
声明一个类中的对象,调用构造函数,建立二叉树,并输出四种遍历结果,检验输出结果。
intmain(){
BiTreeshu;
//声明类中一个对象,在构造了一颗树
BiNode*root=shu.Getroot();
//获取指向根结点的指针
cout
程序结构:
主函数建立一个类模板定义构造函数,析构函数,以及成员函数声明类中的一个对象调用构造函数,构造一颗二叉树层序遍历二叉树后序遍历二叉树中序遍历二叉树前序遍历二叉树获取该二叉树的根节点将结果输出,人工检验源代码:
#includeusingnamespacestd;
templatestructBiNode
Tdata;
BiNode*lchild,*rchild;
};
templateclassBiTree
{public:
BiTree();
//构造函数,初始化一棵二叉树~BiTree(void);
//析构函数,释放二叉链表中各结点的存储空间
BiNode*Getroot();
//获得指向根结点的指针
voidxianxu(BiNode*root);
//前序遍历二叉树
voidzhongxu(BiNode*root);
//中序遍历二叉树
voidhouxu(BiNode*root);
//后序遍历二叉树
voidcengxu(BiNode*root);
//层序遍历二叉树private:
BiNode*root;
BiNode*Creat();
voidRelease(BiNode*root);
};
templateBiTree:
if(aa=="
else{
//生成一个结点
returnroot;
}
~BiTree(void){Release(root);
//析构函数,释放存储指针所需要的空间}
Getroot()//获取根节点所在指针的位置{returnroot;
templatevoidBiTree:
//如果节点为空,则返回空
coutdata
//先序遍历树的左子树
}}
//中序递归遍历root的左子树
//如果节点为空,返回空
houxu(root->
//后序递归遍历root的左子树
//后序递归遍历root的右子树
cengxu(BiNode*root){
constintMaxSize=100;
//利用队列的方法对树进行层序遍历
BiNode*Q[MaxSize];
BiNode*q;
//如果节点为空,返回空
//若节点不为空,则该节点入队
while(front!
//只要队列不为空,则节点依次出队
}}}
Release(BiNode*root)//析构函数,释放存储空间{
if(root!
=NULL){
Release(root->
//释放左子树
//释放右子树
deleteroot;
BiTreeshu;
通过对结果的分析,发现输出结果与建立二叉树时的输入完全符合,说明程序的运行结果是正确的。
心得体会:
1)函数递归的方法可以在相当程度上使程序简洁,避免代码的冗长复杂。
2)构造函数如果带参数,在声明对象的时候应该将实参指出来。
但是本题中构造函数位递归调用,初始的根节点的数据值由键盘输入,因此无法在声明对象时引入实参。
所以最后选择了无参但是引用了this指针的构造函数。
可见,对于构造函数的含参调用应该小心谨慎。
3)编程时,要不停得检验自己的输入与输出,必要的时候需要人工进行计算,以保证程序的运行按照预先的设想。
第二篇:
数据结构树和二叉树代码
树和二叉树
一、实验目的:
参照给定的二叉树类的程序样例,验证给出的有关二叉树的常见算法,并实现有关的操作。
二、实验要求:
1、掌握二叉树、哈夫曼树和树的特点。
掌握它们的常见算法。
2、提交实验报告,报告内容包括:
目的、要求、算法描述、程序结构、主要变量说明、程序清单、调试情况、设计技巧、心得体会。
三、实验内容:
1.设计实现二叉树类,要求:
(1)编写一个程序,首先建立不带头结点的二叉链式存储结构的二叉树,然后分别输出按照前序遍历二叉树、中序遍历二叉树和后序遍历二叉树访问各结点的序列信息,最后再测试查找函数和撤销函数的正确性。
(2)实现二叉树层次遍历的非递归算法。
(3)假设二叉树采用链式存储结构进行存储,编写一个算法,输出一个二叉树的所有叶子结点,并统计叶子结点个数。
(4)编写求二叉树高度的函数(5)编写一主函数来验证算法实现。
2.设计实现二叉线索链表类,要求:
(1)编写一个程序,首先建立中序线索链表的二叉树,然后实现中序线索链表的遍历算法。
(2)编写一主函数来验证算法实现。
*3.编写创建哈夫曼树和生成哈夫曼编码的算法。
*4.假设二叉树采用链式存储结构进行存储,试设计一个算法,输出从每个叶子结点到根结点的路径。
*5.假设二叉树采用链式存储结构进行存储,试设计一个算法,求二叉树的宽度(即具有结点数最多的层次上结点总数)
四、程序样例
#include#includeusingnamespacestd;
templatestructBiNode{Tdata;
BiNode*lchild,*rchild;
intmax(inta,intb){returna>
b?
a:
b;
}templateclassBiTree{public:
//构造函数,初始化一棵空的二叉树
~BiTree()//二叉树的析构函数算法BiTree{Release(root);
}voidInOrder(){InOrder(root);
}//中序遍历二叉树
voidPreOrder(){PreOrder(root);
}voidPostOrder(){PostOrder(root);
}//后序遍历二叉树
voidLeverOrder(){LeverOrder(root);
}//层序遍历二叉树
voidCount(){Count(root);
}voidPreOrdercnt(){PreOrdercnt(root);
}intDepth(){intwww=Depth(root);
returnwww;
}private:
BiNode*root;
//指向根结点的头指针
voidCreat(BiNode*&
root);
voidPreOrder(BiNode*root);
//前序遍历二叉树voidInOrder(BiNode*root);
voidPostOrder(BiNode*root);
voidLeverOrder(BiNode*root);
//层序遍历二叉树
//析构函数调用
voidCount(BiNode*root);
/////求二叉树的结点个数
voidPreOrdercnt(BiNode*root);
///设计算法按前序次序打印二叉树中的叶子结点;
intDepth(BiNode*root);
//深度;
BiTree(){Creat(root);
}templatevoidBiTree:
Creat(BiNode*&
root){charch;
cin>
>
ch;
if(ch=='
#'
)root=NULL;
//建立一棵空树
else{
root=newBiNode;
//生成一个结点
data=ch;
Creat(root->
//递归建立左子树
//递归建立右子树}}templatevoidBiTree:
LeverOrder(BiNode*root){BiNode*Q[100];
intfront=0,rear=0;
//采用顺序队列,并假定不会发生上溢if(root==NULL)return;
Q[++rear]=root;
while(front!
=rear){BiNode*q=Q[++front];
coutdatalchild!
=NULL)Q[++rear]=q->
if(q->
rchild!
}}templatevoidBiTree:
PostOrder(BiNode*root){if(root==NULL)return;
//递归调用的结束条件
PostOrder(root->
//后序递归遍历root的左子树
PostOrder(root->
rchild);
}}templatevoidBiTree:
PreOrder(BiNode*root){if(root==NULL)return;
coutdatalchild);
//前序递归遍历root的左子树
PreOrder(root->
//前序递归遍历root的右子树}}templatevoidBiTree:
Release(BiNode*root){if(root!
=NULL){
//释放左子树
//释放右子树
}}
InOrder(BiNode*root)//二叉树的中序遍历递归算法InOrder{if(root==NULL)return;
InOrder(root->
//中序递归遍历root的左子树
//中序递归遍历root的右子树
}}intn=0;
templatevoidBiTree:
Count(BiNode*root)//n为全局量并已初始化为0{if(root){Count(root->
n++;
///求二叉树的结点个数Count(root->
}}intcnt=0;
PreOrdercnt(BiNode*root)///设计算法按前序次序打印二叉树中的叶子结点;
{if(root){if(!
lchild&
&
!
rchild)
{coutdata
cnt++;
}PreOrdercnt(root->
PreOrdercnt(root->
}}templateintBiTree:
Depth(BiNode*root)//算法求二叉树的深度{if(root==NULL)return0;
else{inthl=Depth(root->
inthr=Depth(root->
returnmax(hl,hr)+1;
}}intmain(){BiTreemytree;
cout
enumflag{Child,Thread};
//枚举类型,枚举常量Child=0,Thread=1templatestructThrNode//二叉线索树的结点结构{Tdata;
ThrNode*lchild,*rchild;
flagltag,rtag;
templateclassInThrBiTree{public:
InThrBiTree();
//构造函数,建立中序线索链表
~InThrBiTree();
//析构函数,释放线索链表中各结点的存储空间
ThrNode*Getroot();
//获取根结点
ThrNode*Next(ThrNode*p);
//查找结点p的后继voidInOrder(ThrNode*root);
//中序遍历线索链表private:
ThrNode*root;
//指向线索链表的头指针ThrNode*Creat();
//构造函数调用
voidThrBiTree(ThrNode*root);
//构造函数调用voidRelease(ThrNode*root);
//析构函数调用};
#endif//定义类InThrBiTree中的成员函数,文件名为inthrbitree.cpp#include#include#include"
inthrbitree.h"
usingnamespacestd;
//构造一棵中序线索二叉树templateInThrBiTree:
InThrBiTree(){ThrNode*pre=NULL;
this->
ThrBiTree(root);
}//释放中序线索二叉链表中各结点的存储空间templateInThrBiTree:
~InThrBiTree(void){Release(root);
}//获取指向中序线索二叉树根结点的指针templateThrNode*InThrBiTree:
Getroot(){returnroot;
}//输出指向结点p的后继结点的指针templateThrNode*InThrBiTree:
Next(ThrNode*p){ThrNode*q;
if(p->
rtag==Thread)q=p->
//右标志为1,可直接得到后继结点
else{q=p->
//工作指针初始化while(q->
ltag==Child)//查找最左下结点
{q=q->
}}returnq;
//中序遍历一棵线索二叉树templatevoidInThrBiTree:
InOrder(ThrNode*root){ThrNode*p=root;
//如果线索链表为空,则空操作返回while(p->
ltag==Child)//查找中序遍历序列的第一个结点p并访问{p=p->
}coutdatarchild!
=NULL)//当结点p存在后继,依次访问其后继结点{p=Next(p);
coutdataThrNode*InThrBiTree:
Creat(){ThrNode*root;
Tch;
if(ch=="
#"
root=newThrNode;
//生成一个结点root->
data=ch;
root->
ltag=Child;
rtag=Child;
lchild=Creat();
//递归建立左子树root->
rchild=Creat();
//递归建立右子树}returnroot;
}//给二叉树建立线索templatevoidInThrBiTree:
ThrBiTree(ThrNode*root){if(root==NULL)return;
//递归结束条件ThrBiTree(root->
if(!
lchild){//对root的左指针进行处理root->
ltag=Thread;
roo