实验项目
二叉树的基本操作实现及其应用
实验目的
1.熟悉二叉树结点的结构和对二叉树的基本操作。
2.掌握对二叉树每一种操作的具体实现。
3.学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。
4.会用二叉树解决简单的实际问题。
实验内容
设计程序实现二叉树结点的类型定义和对二叉树的基本操作。该程序包括二叉树结构类型以及每一种操作的具体的函数定义和主函数。
1、采用二叉树链表作为存储结构,
2、递归建立一个二叉树
4、按(A:先序 B:中序 C:后序 )遍历输出二叉树的所有结点
5、输出二叉树(凹入式)
以上必做,以下选做
6、求二叉树中所有结点数
7、求二叉树的深度
8、求二叉树叶子结点数
9、创建二叉树其他方法
10、图形打印二叉树
(一)数据结构的定义
在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
一棵深度为k,且有2k-1个节点的二叉树,称为满二叉树。这种树的特点是每一层上的节点数都是最大节点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。具有n个节点的完全二叉树的深度为floor(log2n)+1。深度为k的完全二叉树,至少有2(k-1)个叶子节点,至多有2^k-1个节点。
二叉树存储结构定义为:
/*定义二叉树存储结构*/
typedef struct node
{
datatype data;
struct node *lchild,*rchild;
}treenode,*treelist;
(二)总体设计
实验总共包括八个函数:主函数,树初始化函数,根据先序序列和中序序列创建二叉树函数,先序创建二叉树函数,先序遍历算法函数,中序遍历算法函数,后序遍历算法函数,打印二叉树函数。
主函数:统筹调用各个函数以实现相应功能
Int main()
void execute()
树初始化函数:建立树的初始化
void treeinit(treelist &bt)
根据先序序列和中序序列创建二叉树函数:根据先序序列和中序序列创建二叉树
treelist treecreate4(char *p,char *m,int len)
先序创建二叉树函数函数:根据先序序列创建二叉树
treelist treecreate()
先序遍历二叉树函数:利用先序遍历的方法遍历整棵树
void DLR( node *root )
中序遍历二叉树函数:利用中序遍历的方法遍历整棵树
void LDR(node *root)
后序遍历二叉树函数:利用后序遍历的方法遍历整棵树
void LRD (node *root)
打印二叉树函数:利用递归的方法打印整棵树
void printInorder(node *root,int height,string to,int len)
void printTree(node *root)
(三)各函数的详细设计:
主函数main()
主要就是进行功能的实现。
树初始化函数void treeinit(treelist &bt):
建立树的初始化
根据先序序列和中序序列创建二叉树函数treelist treecreate4(char *p,char *m,int len):
根据先序序列和中序序列创建二叉树,判断根节点的位置以及叶子节点,通过一层一层的递归实现创建。
先序创建二叉树函数函数treelist treecreate():
根据先序序列创建二叉树,通过输入一个一个的字符创建二叉树,也是通过递归实现,一‘-’表示该节点为空。
先序遍历二叉树函数void DLR( node *root ):
利用先序遍历的方法遍历整棵树,先从跟节点开始,后左右遍历。
中序遍历二叉树函数void LDR(node *root):
利用中序遍历的方法遍历整棵树,先从左孩子开始,再根节点,最后遍历右孩子。
后序遍历二叉树函数void LRD (node *root):
利用后序遍历的方法遍历整棵树,先从左孩子开始,之后从右孩子遍历,最后再根节点。
打印二叉树函数void printInorder(node *root,int height,string to,int len) void printTree(node *root):
利用递归的方法打印整棵树
实验测试结果
先序和中序结果:
先序创建结果:
实验总结:(100字到200字)
此部分附上主要程序代码和相关的注释说明、调试数据及过程、问题及解决办法。 (最重要)
(1)调试过程中主要遇到哪些问题?是如何解决的?
答:在建立二叉树的时候还是遇见过一些问题的,就拿先序和中序创建来说,找位置有一些难度,看了老师的代码才发现并没有自己想的那么复杂。还有打印二叉树,说实话,还是不怎么会,这个代码是网上参考的,后面要多加思考,争取能够自己写出打印二叉树的函数。
(2)经验和体会
答:还是那句老话,多敲代码自己练习,有时间把多复习多上网查查资料,增加自己对二叉树数据结构的理解。
附录 实验程序代码(该部分请加注释)
/tree.h函数代码/
typedef struct node
{
datatype data;
struct node *lchild,*rchild;
}treenode,*treelist;
//树初始化
void treeinit(treelist &bt)
{
bt=NULL;
}
treelist treecreate4(char *p,char *m,int len) //根据先序序列和中序序列创建二叉树;
{
//*P存放先序序列,*m存放中序序列,len为m中字符个数;
treelist s;
char *q;
int k;
if(len<=0)
return NULL;
s=new treenode(); //创建二叉树结点s;
s->data=*p;
figure++;
for(q=m;qlchild=treecreate4(p+1,m,k); //递归构造左子树;
s->rchild=treecreate4(p+k+1,q+1,len-k-1); //递归构造右子树;
return s;
}
treelist treecreate() //先序创建二叉树
{
treelist s;
char c;
std::cin>>c;
if(c == '-'){
s = NULL;
}else{
s = new treenode();
s->data = c;
figure++; //构造根结点
s->lchild = treecreate(); //构造左子树
s->rchild = treecreate(); //构造右子树
}
return s;
}
//先序遍历算法
void DLR( node *root )
{
if (root !=NULL) //非空二叉树
{
cout<data; //访问D
DLR(root->lchild); //递归遍历左子树
DLR(root->rchild); //递归遍历右子树
}
}
//中序遍历算法
void LDR(node *root)
{
if(root !=NULL)
{
LDR(root->lchild);
cout<data;
LDR(root->rchild);
}
}
//后序遍历算法
void LRD (node *root)
{
if(root !=NULL)
{
LRD(root->lchild);
LRD(root->rchild);
cout<data;
}
}
void printInorder(node *root,int height,string to,int len)
{
if(NULL == root)
return ;
printInorder(root->rchild,height+1,"_",len);//先打印右子树
//打印跟节点
stringstream ss;
ss << root->data;
string val = to + ss.str() + to;
int lenM = val.length();
int lenL = (len-lenM)/2;
int lenR = len -lenM-lenL;
val = string(lenL,' ') + val + string(lenR,' ');
std::cout<lchild,height+1,"_",len);
return ;
}
void printTree(node *root)
{
cout << "Binary Tree:" << endl;
printInorder(root,0,"_",5);
cout << endl;
}
/menu.h菜单函数代码/
#ifndef MENU_H_INCLUDED
#define MENU_H_INCLUDED
void menu(){
std::cout<<"\n";
std::cout<<" **********************二叉树的应用**********************\n";
std::cout<<" * *\n";
std::cout<<" * a:(先中)创建二叉树 b:先序创建二叉树 *\n";
std::cout<<" * c:先序遍历 d:中序遍历 *\n";
std::cout<<" * e:后序遍历 f:二叉树的节点数 *\n";
std::cout<<" * g:打印二叉树(凹入型) h:退出程序 *\n";
std::cout<<" * *\n";
std::cout<<" ********************************************************\n";
}
#endif // MENU_H_INCLUDED
/主函数代码/
#include
#include
#include
#include
using namespace std;
#define maxsize 100
#define infinity 10000 /*定义一个无限大的值*/
typedef char datatype;
int figure=0;//所含结点个数
#include "menu.h"
#include "tree.h"
typedef treelist elem;
char str1[100],str2[100];
int i,j,length;//lever表示层次,h高度
treelist bt;
int main()
{
treeinit(bt);
void execute();
execute();
return 0;
}
void execute()
{
char a;
for(;;)
{
menu();
cin>>a;
switch (a)
{
case 'a':
cout<<"请输入先序序列和中序序列:"<>str1>>str2;
length=strlen(str1);
bt=treecreate4(str1,str2,length);
break;
case 'b':
cout<<"请输入先序序列:"<