简介:“种”了一棵顺序存结构存储string类型结点的二叉树,并层序输出结点的数据,并实现各个结点的“自我介绍”,内容包括自己、双亲、孩子、兄弟。
直接上“码”
类的定义:
#include<iostream>
#include<string>
using namespace std;
const int MaxSize=100;
class TreeQ
{
public:
TreeQ()
{
int i;
for(i=0;i<MaxSize;i++)
{
Tree[i]="none";
}
}
void createTreeQ(string Tree[]);
~TreeQ(){}
int TreeEmpty(string Tree[]);
void leverPrint(string Tree[]);
string Parent(string Tree[],string e);
string Lchild(string Tree[],string e);
string Rchild(string Tree[],string e);
string Lsibling(string Tree[],string e);
string Rsibling(string Tree[],string e);
string Print_leave(string Tree[]);
void Print_family(string Tree[]);
private:
string Tree[MaxSize];
};
函数定义
void TreeQ::createTreeQ(string Tree[])
{
int i=0;
int j;
cout<<"请按层序输入结点的值(字符串),none表示空节点,输入out结束,结点数为<="<<MaxSize<<":"<<endl;
while(1)
{
cin>>Tree[i];
if(Tree[i]=="out")
{
Tree[i]="none";
j=i;
for(j;j<MaxSize;j++)
{
Tree[j]="none";
}
break;
}
i++;
};
}
int TreeQ::TreeEmpty(string Tree[])
{
if(Tree[0]=="none")
return 1;
else
return 0;
}
void TreeQ::leverPrint(string Tree[])
{
int i=MaxSize-1,j;
while(Tree[i]=="none")
i--; //找到最后一个非空的结点
for(j=0;j<=i;j++)
{
if(Tree[j]!="none")
{
cout<<Tree[j]<<'\t';
}
}
}
string TreeQ::Parent(string Tree[],string e)
{
int i;
if(Tree[0]=="none")
return "none";
for(i=1;i<MaxSize;i++)
{
if(Tree[i]==e)
{
return Tree[(i+1)/2-1];
}
}
return "none";
}
string TreeQ::Lchild(string Tree[],string e)
{
int i;
if(Tree[0]=="none")
return "none";
for(i=0;i<MaxSize;i++)
{
if(Tree[i]==e)
{
return Tree[i*2+1];
}
}
return "none";
}
string TreeQ::Rchild(string Tree[],string e)
{
int i;
if(Tree[0]=="none")
return "none";
for(i=0;i<MaxSize;i++)
{
if(Tree[i]==e)
{
return Tree[i*2+2];
}
}
return "none";
}
string TreeQ::Lsibling(string Tree[],string e)
{
int i;
if(Tree[0]=="none")
return "none";
for(i=1;i<MaxSize;i++)
{
if(Tree[i]==e&&i%2==0) //找到e且序号为偶数
{
return Tree[i-1];
}
}
return "none";
}
string TreeQ::Rsibling(string Tree[],string e)
{
int i;
if(Tree[0]=="none")
return "none";
for(i=1;i<MaxSize;i++)
{
if(Tree[i]==e&&i%2) //找到e且序号为奇数
{
return Tree[i+1];
}
}
return "none";
}
string TreeQ::Print_leave(string Tree[])
{
int i=MaxSize-1,j;
if(Tree[0]=="none")
return "none";
else{
while(Tree[i]!="none")
i--; //找到最后一个非空的结点
for(j=0;j<i;j++)
{
if(Tree[j]!="none"&&Tree[2*j+1]=="none"&&Tree[2*j+2]=="none")
{
cout<<Tree[j]<<'\t';
}
}
return "结束";
}
}
void TreeQ::Print_family(string Tree[])
{
int i=MaxSize-1,j;
while(Tree[i]=="none")
i--; //找到最后一个非空的结点
for(j=0;j<=i;j++)
{
if(Tree[j]!="none")
{
cout<<"我是"<<Tree[j]<<",";
cout<<"双亲是"<<Parent(Tree,Tree[j])<<",";
cout<<"左孩子是"<<Lchild(Tree,Tree[j])<<",";
cout<<"右孩子是"<<Rchild(Tree,Tree[j])<<",";
cout<<"左兄弟是"<<Lsibling(Tree,Tree[j])<<",";
cout<<"右兄弟是"<<Rsibling(Tree,Tree[j])<<'\n'<<endl;
}
}
}
主函数
int main()
{
string Tree[MaxSize];
string e;
TreeQ one;
one.createTreeQ(Tree);
cout<<'\n'<<"输出为1,表示树为空,输出为0,表示树不为空:"<<'\t'<<one.TreeEmpty(Tree)<<endl;
cout<<"层序输出"<<endl;
one.leverPrint(Tree);
cout<<'\n'<<"请问需要查询谁的双亲"<<endl;
cin>>e;
cout<<'\n'<<"双亲是:"<<one.Parent(Tree,e)<<endl;
cout<<'\n'<<"请问需要查询谁的左孩子"<<endl;
cin>>e;
cout<<'\n'<<"左孩子是:"<<one.Lchild(Tree,e)<<endl;
cout<<'\n'<<"请问需要查询谁的右孩子"<<endl;
cin>>e;
cout<<'\n'<<"右孩子是:"<<one.Rchild(Tree,e)<<endl;
cout<<'\n'<<"请问需要查询谁的左兄弟"<<endl;
cin>>e;
cout<<'\n'<<"左兄弟是:"<<one.Lsibling(Tree,e)<<endl;
cout<<'\n'<<"请问需要查询谁的右兄弟"<<endl;
cin>>e;
cout<<'\n'<<"右兄弟是:"<<one.Rsibling(Tree,e)<<endl;
cout<<'\n'<<"叶子有:";
one.Print_leave(Tree);
cout<<'\n'<<endl;
cout<<"接下来是自我介绍:"<<endl;
one.Print_family(Tree);
return 0;
}
我“种”的树长这样的
在运行截图中是这样的
总结
1. 在顺序存储结构中,使用了一组连续的存储单元存放结点。序号为i的结点(根结点除外),其双亲序号为(i+1)/2-1,其左右孩子的序号分别为2i+1和2i+2
2. 二叉树的顺序存储结构比较适合存完全二叉树或近完全二叉树,树中结点的序号可以唯一反映出结点之间的逻辑关系同时节省空间,否则会浪费大量的存储空间去存放空结点。
3.我“种”的是一颗普通的二叉树,但只需要增加一个空的结点,就可以补全为完全二叉树,所以这棵树适合用顺序存储的方法来“种”;另一方面在写程序时没有想到使用递归函数,而是采用了for循环,导致程序代码比较繁杂;但是清晰易懂。
“种”树的过程还是很好玩的,有事没事就多“种”树,种多了就知道种的方法了!