二叉树的基本操作及应用
一、实验目的
1、熟练掌握二叉树的逻辑结构和存储结构。
2、熟练掌握二叉树的各种遍历算法。
二、实验内容
[问题描述]
建立一棵二叉树,试编程实现二叉树的如下基本操作:
- 按先序序列构造一棵二叉链表表示的二叉树T;
- 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列;
- 求二叉树的深度/结点数目/叶结点数目;
- 将二叉树每个结点的左右子树交换位置。
[基本要求]
从键盘接受输入(先序),以二叉链表作为存储结构,建立二叉树(以先序来建立),
[测试数据]
如输入:ABCффDEфGффFффф(其中ф表示空格字符)
则输出结果为
先序:ABCDEGF
中序:CBEGDFA
后序:CGEFDBA
层序:ABCDEFG
[实验步骤]
㈠、数据结构与核心算法的设计描述
-
二叉树的存储类型定义
typedef struct BiTNode{
char data;//结点数据域
struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree; -
创建二叉链表表示的二叉树
void CreateBiTree(BiTree &T)//先序输入二叉树中结点的值(char)
{参数:二叉树(BiTree T)} -
遍历二叉树
void PreOrderTraverse(BiTree T)//先序遍历二叉树
{参数:二叉树(BiTree T)}
void InOrderTraverse(BiTree T)//中序遍历二叉树
{参数:二叉树(BiTree T)}
void PostOrderTraverse(BiTree T)//后续遍历二叉树
{参数:二叉树(BiTree T)}
int Depth(BiTree T)//计算二叉树的深度
{参数:二叉树(BiTree T)}
int NodeCount(BiTree T)//计算二叉树的结点数
{参数:二叉树(BiTree T)}
int LeafNodeCount(BiTree T)//计算二叉树的叶子结点数
{参数:二叉树(BiTree T)}
int Exchange(BiTree T,BiTree &NewT)//交换二叉树的左右子树
{参数:二叉树(BiTree T,BiTree NewT)}
㈡、函数调用及主函数设计
int main()
{
BiTree T=new BiTNode;
BiTree NewT=new BiTNode;
cout<<"请先序输入二叉树:";
CreateBiTree(T);
cout<<"输出二叉树:"<<endl;
cout<<"先序输出:";
PreOrderTraverse(T);
cout<<endl;
cout<<"中序输出:";
InOrderTraverse(T);
cout<<endl;
cout<<"后序输出:";
PostOrderTraverse(T);
cout<<"层序输出:";
SequenceTraverse(T);
cout<<endl;
cout<<"二叉树的深度为:"<<Depth(T)<<endl;
cout<<"二叉树的结点个数为:"<<NodeCount(T)<<endl;
cout<<"二叉树的叶结点个数为:"<<LeafNodeCount(T)<<endl;
cout<<"交换二叉树的左右结点中......"<<endl;
Exchange(T,NewT);
cout<<"交换后的二叉树为(先序输出):"<<endl;
PreOrderTraverse(NewT);
return 0;
}
㈢ 程序调试及运行结果分析
三:主要算法流程图及程序清单
#include <iostream>
using namespace std;
typedef struct BiTNode{
char data;//结点数据域
struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;
void CreateBiTree(BiTree T)
{//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin>>ch;
if(ch=='#')T=NULL;//递归结束,建空树
else //递归创建二叉树
{
T=new BiTNode; //生成根节点
T->data=ch;//根节点数据域为ch
CreateBiTree(T->lchild);//递归创建左子树
CreateBiTree(T->rchild);//递归创建右子树
}
}
void PreOrderTraverse(BiTree T)
{
if(T)
{
cout<<T->data; //访问根节点
PreOrderTraverse(T->lchild);//先序遍历左子树
PreOrderTraverse(T->rchild);//先序遍历右子树
}
}
void InOrderTraverse(BiTree T)
{//中序遍历二叉树递归算法
if(T)//若二叉树非空
{
InOrderTraverse(T->lchild);//中序遍历左子树
cout<<T->data; //访问根节点
InOrderTraverse(T->rchild);//中序遍历右子树
}
}
void PostOrderTraverse(BiTree T)
{
if(T)
{
PostOrderTraverse(T->lchild);//后序遍历左子树
PostOrderTraverse(T->rchild);//后序遍历右子树
cout<<T->data; //访问根节点
}
}
void SequenceTraverse(BiTree T)
{
BiTree temp[100]; //创建BiTree指针类型的指针数组
int in=0;
int out=0;
temp[in++]=T;//先保存二叉树根节点
while(in>out)
{
if(temp[out]!=NULL)
{
cout<<temp[out]->data;
temp[in++]=temp[out]->lchild;
temp[in++]=temp[out]->rchild;
}
out++;
}
}
int Depth(BiTree T)
{
int m,n;
if(T==NULL) return 0;//如果是空树,则深度为0
else
{
m=Depth(T->lchild);//m为左子树深度
n=Depth(T->rchild);//n为右子树深度
if(m>n)return (m+1);//二叉树深度为左右子树深度较大者加1
else return (n+1);
}
}
int NodeCount(BiTree T)
{
if(T==NULL)return 0;//如果是空树则结点个数为0
else return NodeCount(T->lchild)+NodeCount(T->rchild)+1;//否则结点数为左子树结点数+右子树结点数
}
int LeafNodeCount(BiTree T)
{
static int LeafNum=0;//叶子初始数目为0,使用静态变量局部变量,防止下一次被初始化
if(T)//树非空
{
if(T->lchild==NULL&&T->rchild==NULL)//为叶子结点
LeafNum++;//叶子数目加1
LeafNodeCount(T->lchild);
LeafNodeCount(T->rchild);
}
return LeafNum;
}
int Exchange(BiTree T,BiTree &NewT)
{
if(T==NULL)//如果是空树,递归结束
{
NewT=NULL;
return 0;
}
else
{
NewT=new BiTNode;
NewT->data=T->data;//复制根节点
Exchange(T->lchild,NewT->rchild);//递归交换左子树
Exchange(T->rchild,NewT->lchild);//递归交换右子树
}
}
int main()
{
BiTree T=new BiTNode;
BiTree NewT=new BiTNode;
cout<<"请先序输入二叉树:";
CreateBiTree(T);
cout<<"输出二叉树:"<<endl;
cout<<"先序输出:";
PreOrderTraverse(T);
cout<<endl;
cout<<"中序输出:";
InOrderTraverse(T);
cout<<endl;
cout<<"后序输出:";
PostOrderTraverse(T);
cout<<"层序输出:";
SequenceTraverse(T);
cout<<endl;
cout<<"二叉树的深度为:"<<Depth(T)<<endl;
cout<<"二叉树的结点个数为:"<<NodeCount(T)<<endl;
cout<<"二叉树的叶结点个数为:"<<LeafNodeCount(T)<<endl;
cout<<"交换二叉树的左右结点中......"<<endl;
Exchange(T,NewT);
cout<<"交换后的二叉树为(先序输出):"<<endl;
PreOrderTraverse(NewT);
return 0;
}