实验五 二叉树操作
一、 实验目的
掌握二叉树的基本概念,二叉树的存储结构使用链表。
二、 实验内容
1、输入一个完全二叉树的层次遍历字符串,创建这个二叉树,输出这个 二叉树的前序遍历字符串、中序遍历字符串、后序遍历字符串、结点 数目、二叉树高度(上述每一个结果独立一行显示)。
2、输入二叉树前序序列和中序序列(各元素各不相同),创建这个二叉 树,输出该二叉树的后序序列、层次遍历。
代码如下:
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<queue>
using namespace std;
int size,count=0;
string s1;
class BtreeNode{
public:
char element;
BtreeNode *leftchild,*rightchild;
int Tsize;
BtreeNode(){leftchild=rightchild=NULL;Tsize=0;}
BtreeNode(char& theE,BtreeNode* theleft=NULL,BtreeNode*theright=NULL){
element=theE;
leftchild=theleft;
rightchild=theright;
Tsize=1;
}
};
int height(BtreeNode *t){
if(t==NULL) return 0;
int hl=height(t->leftchild);
int hr=height(t->rightchild);
if(hl>hr) return++hl;
else return ++hr;
}
void pre(BtreeNode* t){//前序遍历输出
if(t!=NULL){
if(count!=size-1) cout<<t->element<<",";
else cout<<t->element<<endl;
count++;
pre(t->leftchild);
pre(t->rightchild);
}
}
void in(BtreeNode* t){//中序遍历输出
if(t!=NULL){
in(t->leftchild);
if(count!=size-1) cout<<t->element<<",";
else cout<<t->element<<endl;
count++;
in(t->rightchild);
}
}
void post(BtreeNode* t){//后序遍历输出
if(t!=NULL){
post(t->leftchild);
post(t->rightchild);
if(count!=size-1) cout<<t->element<<",";
else cout<<t->element<<endl;
count++;
}
}
void level(BtreeNode* t){//层序遍历输出
queue<BtreeNode*> q;
while(t!=NULL){
if(count!=size-1) cout<<t->element<<",";
else cout<<t->element<<endl;
count++;
if(t->leftchild!=NULL)q.push(t->leftchild);
if(t->rightchild!=NULL)q.push(t->rightchild);
if(q.empty())break;
t=q.front();
q.pop();
}
}
//按层次遍历顺序创建二叉树
void set(BtreeNode *cur,int i,string s){
if((2*i+1)<=s.length()){//如果当前节点既有左子节点,又有右子节点
cur->leftchild=new BtreeNode(s[2*i-1]);
set(cur->leftchild,2*i,s);
cur->rightchild=new BtreeNode(s[2*i]);
set(cur->rightchild,2*i+1,s);
cur->Tsize+=(cur->leftchild->Tsize+cur->rightchild->Tsize);
return;
}
else if(2*i==s.length()){//如果当前节点只有左子节点
cur->leftchild=new BtreeNode(s[2*i-1]);
cur->Tsize+=cur->leftchild->Tsize;
return;
}
else if(2*i>s.length()) return;//如果当前节点没有子节点
}
BtreeNode* rebuild(char preOrder[],char inOrder[],int pStart,int pEnd,int iStart,int iEnd){//(preOrder,inOrder,0,pLen-1,0,iLen-1)
BtreeNode* tree=new BtreeNode(preOrder[pStart]);
if(pStart==pEnd&&iStart==iEnd) return tree;
int root=0;
//找中序遍历中的根节点
for(root=iStart;root<=iEnd;root++)//<=根节点在末尾 没有右子树的情况
if(preOrder[pStart]==inOrder[root]) break;
//划分左右子树
int leftLength=root-iStart;//左子树
int rightLength=iEnd-root;//右子树
//遍历左子树
if(leftLength>0)
tree->leftchild=rebuild(preOrder,inOrder,pStart+1,pStart+leftLength,iStart,root-1);
//遍历右子树
if(rightLength>0)
tree->rightchild=rebuild(preOrder,inOrder,pStart+leftLength+1,pEnd,root+1,iEnd);
return tree;
}
int main(){
cout<<"Input1"<<endl;
string s1,s2,s3,ss;
cin>>s1;
cout<<"Output1"<<endl;
BtreeNode *root1=new BtreeNode(s1[0]);
set(root1,1,s1);
size=s1.length();
//为实现输出最后一个节点元素时换行,利用全局变量count,每输出一个元素+1,输出结束后清零,以便下一次输出
pre(root1);count=0;
in(root1);count=0;
post(root1);count=0;
cout<<root1->Tsize<<endl;
cout<<height(root1)<<endl;
cout<<"Input2"<<endl;
cin>>s2>>s3;
//用字符串读入二叉树前序序列和中序序列,并转化成字符数组对二叉树进行重建
char ch2[s2.length()]; s2.copy(ch2,s2.length(),0);
char ch3[s3.length()]; s3.copy(ch3,s3.length(),0);
cout<<"Output2"<<endl;
BtreeNode *root2=rebuild(ch2,ch3,0,s2.length()-1,0,s3.length()-1);
size=s2.length();
post(root2);count=0;
level(root2);
cout<<"End"<<endl;
return 0;
}
结论分析与体会:
二叉树是非常重要且基础的内容,通过实验学会了根据层次顺序构建二叉树,以及用前序和中序重建二叉树。