该代码的二叉树结点是数字,采用的是用数组存储,一般使用在空结点较少的情况,使用的时候,一定要清楚二叉树元素在数组中的存储顺序特点,比如左右子树序号有什么特点,怎么由孩子结点的找到双亲节点……
如果想了解链式存储二叉树,可以参考http://www.cnblogs.com/-beyond/p/6200478.html
#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;
const int MAX_TREE_SIZE=100;
const int Nil=0;
typedef int TElemType;
typedef int SqBiTree[MAX_TREE_SIZE];
struct position{
//按满二叉树计算
int level,order;
};
//函数声明
void show();
void InitBiTree(SqBiTree T);
void DestroyBiTree(SqBiTree T);
void CreateBiTree(SqBiTree T);
int ClearBiTree(SqBiTree T);
bool EmptyBiTree(SqBiTree T);
int BiTreeDepth(SqBiTree T);
TElemType BiTreeRoot(SqBiTree T);
TElemType GetValue(SqBiTree T,position e);
bool Assign(SqBiTree T,position e,TElemType value);
TElemType Parent(SqBiTree T,TElemType e);
TElemType LeftChild(SqBiTree T,TElemType e);
TElemType RightChild(SqBiTree T,TElemType e);
TElemType LeftSibling(SqBiTree T,TElemType e);
TElemType RightSibling(SqBiTree T,TElemType e);
void InsertChild(SqBiTree T,TElemType p,int LR,SqBiTree c);
void Move(SqBiTree q,int j,SqBiTree T,int i);
void PreOrderTraverse(SqBiTree T,int i);
void InOrderTraverse(SqBiTree T,int i);
void PostOrderTraverse(SqBiTree T,int i);
void LevelOrderTraverse(SqBiTree T);
void Print(SqBiTree T);
int main(){
int x,LR,action;
position p;
TElemType e;
SqBiTree T,s;
show();
while(cin>>action){
switch(action){
case 1:
system("cls");
InitBiTree(T);
cout<<"初始化二叉树成功"<<endl<<endl;
break;
case 2:
system("cls");
CreateBiTree(T);
cout<<"二叉树创建成功"<<endl<<endl;
break;
case 3:
system("cls");
cout<<"先序遍历二叉树,结果为:"<<endl;
PreOrderTraverse(T,0);
cout<<endl<<endl;
break;
case 4:
system("cls");
cout<<"中序遍历二叉树,结果为:"<<endl;
InOrderTraverse(T,0);
cout<<endl<<endl;
break;
case 5:
system("cls");
cout<<"后序遍历二叉树,结果为:"<<endl;
PostOrderTraverse(T,0);
cout<<endl<<endl;
break;
case 6:
system("cls");
cout<<"层序遍历二叉树,结果为:"<<endl;
LevelOrderTraverse(T);
cout<<endl<<endl;
break;
case 7:
system("cls");
cout<<"请输入层数和序号:"<<endl;
cin>>p.level>>p.order;
cout<<"第"<<p.level<<"层"<<" 第"<<p.order<<"个结点的值为: "<<GetValue(T,p);
cout<<endl<<endl;
break;
case 8:
system("cls");
ClearBiTree(T);
cout<<"已清空二叉树"<<endl<<endl;
break;
case 9:
InitBiTree(s);
cout<<"请输入右子树为空的二叉树s:"<<endl;
CreateBiTree(s);
cout<<"待插入的二叉树已经建立,请输入将要插入的结点的值:"<<endl;
cin>>e;
cout<<"待插入的二叉树成为左孩子(0),右孩子(1):"<<endl;
cin>>LR;
InsertChild(T,e,LR,s);
cout<<"操作成功"<<endl<<endl;
break;
case 10:
system("cls");
cout<<"二叉树的各结点为:"<<endl;
Print(T);
cout<<endl;
break;
case 11:
system("cls");
cout<<"请输入双亲结点"<<endl;
cin>>e;
cout<<"左孩子结点的值为: "<<LeftChild(T,e)<<endl;
break;
case 12:
system("cls");
cout<<"请输入双亲结点"<<endl;
cin>>e;
cout<<"右孩子结点的值为: "<<RightChild(T,e)<<endl;
break;
case 13:
system("cls");
cout<<"请输入右兄弟结点"<<endl;
cin>>e;
cout<<"左兄弟结点的值为: "<<LeftSibling(T,e)<<endl;
break;
case 14:
system("cls");
cout<<"请输入左兄弟结点"<<endl;
cin>>e;
cout<<"右兄弟结点的值为: "<<RightSibling(T,e)<<endl;
break;
case 15:
system("cls");
cout<<"请输入孩子结点"<<endl;
cin>>e;
cout<<"双亲结点的值为: "<<Parent(T,e)<<endl;
break;
case 16:
system("cls");
cout<<"二叉树的深度为: "<<BiTreeDepth(T)<<endl;
break;
case 17:
system("cls");
cout<<"根结点的值为: "<<BiTreeRoot(T)<<endl;
break;
case 18:
system("cls");
cout<<"请输入结点的层数和在该层的序号: "<<endl;
cin>>p.level>>p.order;
cout<<"请输入将赋给该结点的值:"<<endl;
cin>>e;
Assign(T,p,e);
cout<<"赋值成功!"<<endl;
break;
}
system("pause");
system("cls");
show();
}
}
void show(){
cout<<"+-----------------------------------------------+"<<endl;
cout<<"| |"<<endl;
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<<"| 9->插入二叉树 |"<<endl;
cout<<"| 10->打印二叉树 |"<<endl;
cout<<"| 11->获取左孩子 |"<<endl;
cout<<"| 12->获取右孩子 |"<<endl;
cout<<"| 13->获取左兄弟 |"<<endl;
cout<<"| 14->获取右兄弟 |"<<endl;
cout<<"| 15->获取结点双亲 |"<<endl;
cout<<"| 16->获取二叉树深度 |"<<endl;
cout<<"| 17->获取根节点 |"<<endl;
cout<<"| 18->给结点赋值 |"<<endl;
cout<<"+-----------------------------------------------+"<<endl;
}
void InitBiTree(SqBiTree T){
int i;
for(i=0;i<MAX_TREE_SIZE;i++){
T[i]=Nil;//初始值为Nil
}
}
void DestroyBiTree(SqBiTree T){
int i;
for(i=0;i<MAX_TREE_SIZE;i++){
T[i]=Nil;//初始值为Nil
}
}
void CreateBiTree(SqBiTree T){
int i=0;
cout<<"请按层需输入结点的值(数字),0表示空结点,以999结束,结点数<"<<MAX_TREE_SIZE<<":"<<endl;
while(1){
cin>>T[i];
if(T[i]==999){
T[i]=Nil;
break;
}
i++;
}
for(i=1;i<MAX_TREE_SIZE;i++){
if(i!=0 && T[(i+1)/2-1]==Nil && T[i]!=Nil){
cout<<"出现无双亲的非根节点!"<<endl;
break;
}
}
}
int ClearBiTree(SqBiTree T){
int i;
for(i=0;i<MAX_TREE_SIZE;i++){
T[i]=Nil;//初始值为Nil
}
}
//判断二叉树是否为空
bool EmptyBiTree(SqBiTree T){
if(T[0]==Nil){
return true;
} else {
return false;
}
}
//获取二叉树的深度
int BiTreeDepth(SqBiTree T){
int i=MAX_TREE_SIZE-1,j=0;
while(i>=0){
//从后往前寻找到第一个结点不是默认值的下标
if(T[i]!=Nil){
break;
}
i--;
}
while(i>=pow(2,j)){
j++;
}
return j;
}
//获取根结点的值
TElemType BiTreeRoot(SqBiTree T){
if(EmptyBiTree(T)){
return Nil;
} else {
return T[0];
}
}
//获取给定结点e的值
TElemType GetValue(SqBiTree T,position e){
return T[int(pow(2,e.level-1)+e.order-2)];
}
//给结点赋值
bool Assign(SqBiTree T,position e,TElemType value){
int i=pow(2,e.level-1)+e.order-2;
if(value!=Nil && T[(i+1)/2-1]==Nil){
cout<<"非法操作,禁止给不含双亲的孩子赋非空值"<<endl;
return false;
}
else if(value==Nil && (T[i*2+1]!=Nil || T[i*2+2]!=Nil)){
cout<<"非法操作,禁止给含有孩子的双亲赋空值"<<endl;
return false;
}
T[i]=value;
return true;
}
//获取双亲结点的值
TElemType Parent(SqBiTree T,TElemType e){
if(!EmptyBiTree(T)){
for(int i=0;i<=MAX_TREE_SIZE;i++){
if(T[i]==e){//判断结点e是否存在与二叉树中
return T[(i+1)/2-1];
}
}
} else {
return Nil;//二叉树为空或者没有结点e
}
}
//获取左孩子的值
TElemType LeftChild(SqBiTree T,TElemType e){
if(!EmptyBiTree(T)){
for(int i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e){//判断结点e是否存在与二叉树中
return T[i*2+1];//返回其左孩子的值
}
}
} else {
return Nil;//二叉树为空或者没有结点e
}
}
//获取右孩子的值
TElemType RightChild(SqBiTree T,TElemType e){
if(!EmptyBiTree(T)){
for(int i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e){//判断结点e是否存在与二叉树中
return T[i*2+2];//返回其左孩子的值
}
}
} else {
return Nil;//二叉树为空或者没有结点e
}
}
//获取左兄弟的值
TElemType LeftSibling(SqBiTree T,TElemType e){
if(!EmptyBiTree(T)){
for(int i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e && i%2==0){//判断结点e是否存在与二叉树中
//并且存在有兄弟,i%2=0为右孩子
return T[i-1];//返回其左兄弟的值
}
}
} else {
return Nil;//二叉树为空或者没有结点e
}
}
//获取右兄弟的值
TElemType RightSibling(SqBiTree T,TElemType e){
if(!EmptyBiTree(T)){
for(int i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e && i%2==1){//判断结点e是否存在与二叉树中
//并且存在有兄弟,i%2==1为左孩子
return T[i+1];//返回其右兄弟的值
}
}
} else {
return Nil;//二叉树为空或者没有右兄弟
}
}
//仔细观察,寻找双亲、左右孩子和左右兄弟的方法都类似
//首先都得判断二叉树是否为空,然后再判断时候该结点是否存在
//最后根据判断返回结点值
//插入二叉树
void InsertChild(SqBiTree T,TElemType p,int LR,SqBiTree c){
//非空二叉树c要插到T中的p结点下面,成为p结点的(左或右)子树
//非空二叉树c与T无交集,且右子树为空,p结点原有的左或右子树成为s的右子树
//LR=0 c成为左子树,LR=1 c成为右子树
int i=0,j,k;
//查找p结点的序号
//int temp=int(pow(2,BiTreeDepth(T)));
//for(j=0;j<temp-1;j++){
// if(T[j]==p){
// break;
// }
//}
//或者
for(j=0;j<MAX_TREE_SIZE;j++){
if(T[j]==p){
break;
}
}
k=2*j+1+LR;//k为c子树将要插入的序号
if(T[k]!=Nil){
Move(T,k,T,2*k+2);
}
Move(c,i,T,k);
}
//移动二叉树
void Move(SqBiTree q,int j,SqBiTree T,int i){
//把从二叉树q的j结点开始的子树 移为 从二叉树T的i结点开始的子树
if(q[2*j+1]!=Nil){//q的左子树不为空
Move(q,(2*j+1),T,(2*i+1));
}
if(q[2*j+2]!=Nil){//q的右子树不为空
Move(q,(2*j+2),T,(2*i+2));
}
T[i]=q[j];
q[i]=Nil;
}
//先序遍历
void PreOrderTraverse(SqBiTree T,int i){
cout<<T[i]<<' ';
if(T[2*i+1]!=Nil){
PreOrderTraverse(T,2*i+1);
}
if(T[2*i+2]!=Nil){
PreOrderTraverse(T,2*i+2);
}
}
//中序遍历
void InOrderTraverse(SqBiTree T,int i){
if(T[2*i+1]!=Nil){
InOrderTraverse(T,2*i+1);
}
cout<<T[i]<<' ';
if(T[2*i+2]!=Nil){
InOrderTraverse(T,2*i+2);
}
}
//后序遍历
void PostOrderTraverse(SqBiTree T,int i){
if(T[2*i+1]!=Nil){
PostOrderTraverse(T,2*i+1);
}
if(T[2*i+2]!=Nil){
PostOrderTraverse(T,2*i+2);
}
cout<<T[i]<<' ';
}
//层序遍历
void LevelOrderTraverse(SqBiTree T){
int i=MAX_TREE_SIZE-1;
while(T[i]==Nil){
i--;
}
for(int j=0;j<=i;j++){
if(T[j]!=Nil){
cout<<T[j]<<' ';
}
}
cout<<endl;
}
//逐层按本层序号输出二叉树
void Print(SqBiTree T){
int j,k;
position p;
TElemType e;
for(j=1;j<=BiTreeDepth(T);j++){
cout<<"第"<<j<<"层: ";
for(k=1;k<=pow(2,j-1);k++){
p.level=j;
p.order=k;
e=GetValue(T,p);
cout<<k<<":"<<e<<" ";
}
cout<<endl;
}
cout<<endl;
}