数据结构-实验五-二叉树的操作
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告实验五二叉树的操作
班级:12卓越6班
学号:**********
*名:***
任课教师:***
计算机与信息工程学院
2014年5月13 日
实验五二叉树的操作
一、实验目的
1.进一步掌握指针变量、动态变量的含义;
2.掌握二叉树的结构特征,以及各种存储结构的特点及适用范围;3.掌握用指针类型描述、访问和处理二叉树的运算。
二、实验要求
1.按实验内容编写实验的程序,主程序以菜单形式运行。
2.上机调试运行本程序。
3.保存和打印出程序的运行结果,并结合程序进行分析。
4.提交源程序和运行结果。
三、实验内容
1.创建以二叉链表作存储结构的二叉树;
2.按中序遍历二叉树;
3.按层次遍历二叉树;
4.计算二叉树的单枝结点数;
5.交换二叉树的左右子树。
解:
//声明类BiTree及定义结构BiNode,文件名为bitree.h
#ifndef BITREE_H
#define BITREE_H
//int num;
template <class T>
struct BiNode //二叉树的结点结构
{
T data;
BiNode<T> *lchild, *rchild;
};
template <class T>
class BiTree
{
public:
BiTree( ); //构造函数,初始化一棵二叉树,其前序序列由键盘输入
~BiTree(void); //析构函数,释放二叉链表中各结点的存储空间BiNode<T>* Getroot(); //获得指向根结点的指针
void PreOrder(BiNode<T> *root); //前序遍历二叉树
void InOrder(BiNode<T> *root); //中序遍历二叉树
void PostOrder(BiNode<T> *root); //后序遍历二叉树
void LeverOrder(BiNode<T> *root); //层序遍历二叉树
int depth(BiNode<T> *root); //求二叉树的深度
void nodenum(BiNode<T> *root); //求二叉树的结点个数
void leafnum(BiNode<T> *root); //求二叉树的叶子结点个数
void empty( ); //判断二叉树是否为空
int printnum( ); // 输出(全部、叶子或单分支)结点数void sbnodenum(BiNode<T> *root); //求二叉树的单分支结点个数
void exchangetree(BiNode<T> *root); //交换二叉树的左右子树
private:
BiNode<T> *root; //指向根结点的头指针
BiNode<T> *p;
BiNode<T> *Creat( ); //有参构造函数调用
void Release(BiNode<T> *root); //析构函数调用
int num;
};
#endif
//定义类中的成员函数,文件名为bitree.cpp
#include<iostream>
#include<string>
#include"bietree.h"
using namespace std;
/*
*前置条件:二叉树不存在
*输入:无
*功能:构造一棵二叉树
*输出:无
*后置条件:产生一棵二叉树
*/
template<class T>
BiTree<T>::BiTree( )
{
this->num=0;
this->root = Creat( );
}
/*
*前置条件:二叉树已存在
*输入:无
*功能:释放二叉链表中各结点的存储空间*输出:无
*后置条件:二叉树不存在
*/
template<class T>
BiTree<T>::~BiTree(void)
{
Release(root);
}
*前置条件:二叉树已存在
*输入:无
*功能:获取指向二叉树根结点的指针*输出:指向二叉树根结点的指针
*后置条件:二叉树不变
*/
template<class T>
BiNode<T>* BiTree<T>::Getroot( )
{
return root;
}
/*
*前置条件:二叉树已存在
*输入:无
*功能:前序遍历二叉树
*输出:二叉树中结点的一个线性排列*后置条件:二叉树不变
*/
template<class T>
void BiTree<T>::PreOrder(BiNode<T> *root) {
if(root==NULL) return;
else{
cout<<root->data<<" ";
PreOrder(root->lchild);
PreOrder(root->rchild);
}
}
*前置条件:二叉树已存在
*输入:无
*功能:中序遍历二叉树
*输出:二叉树中结点的一个线性排列
*后置条件:二叉树不变
*/
template <class T>
void BiTree<T>::InOrder (BiNode<T> *root)
{
if (root==NULL) return; //递归调用的结束条件
else{
InOrder(root->lchild); //中序递归遍历root的左子树
cout<<root->data<<" "; //访问根结点的数据域
InOrder(root->rchild); //中序递归遍历root的右子树}
}
/*
*前置条件:二叉树已存在
*输入:无
*功能:后序遍历二叉树
*输出:二叉树中结点的一个线性排列
*后置条件:二叉树不变
*/
template <class T>
void BiTree<T>::PostOrder(BiNode<T> *root)
{
if (root==NULL) return; //递归调用的结束条件
else{
PostOrder(root->lchild); //后序递归遍历root的左子树
PostOrder(root->rchild); //后序递归遍历root的右子树
cout<<root->data<<" "; //访问根结点的数据域}
}
/*
*前置条件:二叉树已存在
*输入:无
*功能:层序遍历二叉树
*输出:二叉树中结点的一个线性排列
*后置条件:二叉树不变
*/
template <class T>
void BiTree<T>::LeverOrder(BiNode<T> *root)
{
const int MaxSize = 100;
int front = 0;
int rear = 0; //采用顺序队列,并假定不会发生上溢
BiNode<T>* Q[MaxSize];
BiNode<T>* q;
if (root==NULL) return;
else{
Q[rear++] = root;
while (front != rear)
{
q = Q[front++];
cout<<q->data<<" ";
if (q->lchild != NULL) Q[rear++] = q->lchild;
if (q->rchild != NULL) Q[rear++] = q->rchild;
}
}
}
/*
*前置条件:空二叉树
*输入:数据ch;
*功能:初始化一棵二叉树,构造函数调用
*输出:无
*后置条件:产生一棵二叉树
*/
template <class T>
BiNode<T>* BiTree<T>::Creat( )
{
BiNode<T>* root;
T ch;
cout<<"请输入创建一棵二叉树的结点数据"<<endl;
cin>>ch;
if (ch=="#") root = NULL;
else{
root = new BiNode<T>; //生成一个结点
root->data=ch;
root->lchild = Creat( ); //递归建立左子树
root->rchild = Creat( ); //递归建立右子树}
return root;
}
/*
*前置条件:二叉树已经存在
*输入:无
*功能:释放二叉树的存储空间,析构函数调用*输出:无
*后置条件:二叉树不存在
*/
template<class T>
void BiTree<T>::Release(BiNode<T>* root)
{
if (root != NULL){
Release(root->lchild); //释放左子树
Release(root->rchild); //释放右子树
delete root;
}
}
/*
*前置条件:二叉树已经存在
*输入:无
*功能:求二叉树的深度
*输出:二叉树的深度
*后置条件:二叉树不变
*/
template<class T>
int BiTree<T>::depth(BiNode<T> *root)
{
int n,m;
if(root==NULL) return 0;
else{
n=depth(root->lchild); //左子树的深度
m=depth(root->rchild); //右子树的深度
if (n>m)
return n+1;
else
return m+1;
}
}
/*
*前置条件:二叉树已经存在
*输入:无
*功能:求二叉树的结点个数
*输出:二叉树的结点个数
*后置条件:二叉树不变
*/
template<class T>
void BiTree<T>::nodenum(BiNode<T> *root)
{
if(root==NULL) return;
else{
num++;
nodenum(root->lchild); //左子树的结点个数
nodenum(root->rchild); //右子树的结点个数}
}
*前置条件:二叉树已经存在
*输入:无
*功能:求二叉树2 的叶子结点个数
*输出:二叉树的叶子结点个数
*后置条件:二叉树不变
*/
template<class T>
void BiTree<T>::leafnum(BiNode<T> *root)
{
if(root==NULL) return;
else
{
if(!(root->lchild) && !(root->rchild)) //判断是否为叶子结点num++;
leafnum(root->lchild); //左子树中的叶子结点个数
leafnum(root->rchild); //右子树中的叶子结点个数}
}
/*
将全局变量num初始化为0
*/
template<class T>
void BiTree<T>::empty( )
{
num=0;
}
输出全局变量num的值
*/
template<class T>
int BiTree<T>::printnum( )
{
return num;
}
/*
*前置条件:二叉树已经存在
*输入:无
*功能:求二叉树的单分支结点个数
*输出:二叉树的单分支结点个数
*后置条件:二叉树不变
*/
template<class T>
void BiTree<T>::sbnodenum(BiNode<T> *root)
{
if(root==NULL) return;
else
{
if((!(root->lchild) && (root->rchild))||((root->lchild) && !(root->rchild))) //判断是否为叶子结点
num++;
sbnodenum(root->lchild); //左子树中的叶子结点个数
sbnodenum(root->rchild); //右子树中的叶子结点个数
}
}
/*
*前置条件:二叉树已经存在
*输入:无
*功能:交换二叉树的左右子树
*输出:无
*后置条件:二叉树左右子树交换
*/
template<class T>
void BiTree<T>::exchangetree(BiNode<T> *root)
{
if(root==NULL) return;
else
{
if((root->rchild)&&(root->lchild)) //判断左右叶子结点都存在
{ p=root->lchild;
root->lchild=root->rchild;
root->rchild=p;
}
exchangetree(root->lchild); //左子树中的叶子结点个数
exchangetree(root->rchild); //右子树中的叶子结点个数}
}
/* BiNode<T> * Q[20];
BiNode<T> *q;
int front=-1;
int rear=-1;
int n=0;int m=0;
Q[++rear]=root;
if(root==NULL)
cout<<0;
else
{
while(front!=rear)
{
q=Q[++front];
if(q->lchild==NULL && q->rchild!=NULL)
m++;
if(q->lchild!=NULL && q->rchild==NULL)
n++;
if(q->lchild!=NULL) Q[++rear]=q->lchild;
if(q->rchild!=NULL) Q[++rear]=q->rchild;
}
}
cout<<"单分支节点的个数为:"<<m+n<<endl;
*/
//二叉树的主函数,文件名为bitreemain.cpp
#include<iostream>
#include<string>
#include"bietree.cpp"
using namespace std;
void main()
{
BiTree<string> bt; //创建一棵树
BiNode<string>* root = bt.Getroot( ); //获取指向根结点的指针int s=-1;
while(s!=0)
{
cout<<"1.前序遍历"<<endl;
cout<<"2.中序遍历"<<endl;
cout<<"3.后序遍历"<<endl;
cout<<"4.层序遍历"<<endl;
cout<<"5.树的深度"<<endl;
cout<<"6.叶子节点个数"<<endl;
cout<<"7.单分支结点个数"<<endl;
cout<<"8.左右子树交换后的结果"<<endl;
cout<<"0.退出"<<endl;
cin>>s;
switch(s)
{ case 1:
bt.PreOrder(root);
cout<<endl;
break;
case 2:
bt.InOrder(root);
cout<<endl;
break;
case 3:
bt.PostOrder(root);
cout<<endl;
break;
case 4:
bt.LeverOrder(root);
cout<<endl;
break;
case 5:
cout<<"树的深度为:"<<bt.depth(root)<<endl;
break;
case 6:
bt.empty();
bt.leafnum(root);
cout<<"叶子结点个数为:"<<bt.printnum()<<endl;
break;
case 7:
bt.empty();
bt.sbnodenum(root);
cout<<"单分支结点个数为:"<<bt.printnum()<<endl;
break;
case 8:
bt.empty();
bt.exchangetree(root);
cout<<"左右子树交换后的结果:";
bt.PreOrder(root);
cout<<endl;
break;
case 0:
exit(0);
}
}
}。