数据结构
孩子兄弟树是一种常见的树结构,与二叉树不同,他能够允许一个父结点拥有多个子结点。其结点的格式为:第一个孩子结点指针,指向下一个兄弟的指针以及数据域。
对于如下一颗孩子兄弟树
其真实的链接方式为
孩子兄弟树和二叉树同样通过递归来实现遍历
先根遍历:A B C E G F D
后根遍历:B G E F C D A
层次遍历:A B C D E F G
代码实现
环境及程序说明
/*
- 环境:Dev C++ TDM-GCC 4.9.2 64-bit Profiling
- 输出大小: 1.88731002807617 MiB
- 编译时间: 0.72s
- 孩子兄弟树基础操作:先根遍历 后根遍历 层次遍历
- 插入根结点 插入结点 删除结点
输出结点个数 输出树高度 搜索结点
搜索父亲结点 搜索上一个兄弟结点
*/
头文件
#include<iostream>
#include<queue>
using namespace std;
结点类及函数
template <class T>
class CBNode{
friend Tree<T>;
private:
CBNode<T> * firstchild; //孩子结点
T data;
CBNode<T> * nextbrother; //兄弟结点
public:
//构造函数
CBNode(){ firstchild = nextbrother = NULL; }
CBNode(const T & d,CBNode<T> * f,CBNode<T> * n):data(d),firstchild(f),nextbrother(n){}
};
树类及函数
template <class T>
class Tree{
friend CBNode<T>;
private:
CBNode<T> * root; //根结点
void FirstRoot(CBNode<T> * t); //先根遍历
void LastRoot(CBNode<T> * t); //后根遍历
void Release(CBNode<T> * t); //释放结点及子节点
CBNode<T> * search(T e,CBNode<T> * t); //搜索结点t下的e并返回指针
CBNode<T> * search(T e){ return search(e,root); }; //搜索整个树中的e并返回指针
CBNode<T> * searchbrother(CBNode<T> * p); //搜索离p最近的兄弟
CBNode<T> * searchparent(CBNode<T> * p); //搜索p的父亲
int Height(CBNode<T> * t); //返回树的高度
int CountChild(CBNode<T> * t); //返回t结点下结点个数
public:
Tree(){ root = NULL; } //构造函数
~Tree(){ Release(root); } //析构函数
bool InsertFirst(T r); //插入根结点
bool Insert(T f,T s); //插入结点
bool Delete(T k); //删除结点
void FirstRoot(){ FirstRoot(root); }; //先根遍历
void LastRoot(){ LastRoot(root); }; //后根遍历
void LevelOrder(); //层次遍历
int CountChild(T e){
CBNode<T> * p = search(e);
return CountChild(p->firstchild);
}
int Height(){ return Height(root); } //返回树高度
};
template <class T>
bool Tree<T>::InsertFirst(T r)
{
if(root)
{
cout<<"该树已有首节点,请释放后插入"<<endl;
return false;
}
CBNode<T> * p = new CBNode<T>(r,NULL,NULL);
root = p;
return true;
}
template <class T>
bool Tree<T>::Insert(T f,T s)
{
CBNode<T> * q = search(f);
if(!q)
{
cout<<"插入失败,找不到节点:"<<s<<endl;
return false;
}
CBNode<T> * p = new CBNode<T>(s,NULL,NULL);
CBNode<T> * r = NULL;
if(!(q->firstchild))
{
q->firstchild = p;
return true;
}
else
{
r = q->firstchild;
while(r->nextbrother)
{
r = r->nextbrother;
}
r->nextbrother = p;
return true;
}
return false;
}
template <class T>
bool Tree<T>::Delete(T k)
{
CBNode<T> * p = search(k);
CBNode<T> * b = searchbrother(p);
CBNode<T> * f = searchparent(p);
if(p == root)
{
cout<<"根结点无法删除"<<endl;
return false;
}
if(b && !p->firstchild && !p->nextbrother)
{
b->nextbrother = NULL;
delete p;
return true;
}
if(b && !p->firstchild && p->nextbrother)
{
b->nextbrother = p->nextbrother;
delete p;
return true;
}
if(b && p->firstchild && !p->nextbrother)
{
b->nextbrother = p->firstchild;
delete p;
return true;
}
if(b && p->nextbrother && p->firstchild)
{
b->nextbrother = p->firstchild;
CBNode<T> * temp = p->firstchild;
while(temp->nextbrother)
temp = temp->nextbrother;
temp->nextbrother = p->nextbrother;
delete p;
return true;
}
if(!b && !p->firstchild && p->nextbrother)
{
f->firstchild = p->nextbrother;
delete p;
return true;
}
if(!b && p->firstchild && p->nextbrother)
{
f->firstchild = p->firstchild;
CBNode<T> * temp = p->firstchild;
while(temp->nextbrother)
temp = temp->nextbrother;
temp->nextbrother = p->nextbrother;
delete p;
return true;
}
if(!b && p->firstchild && !p->nextbrother)
{
f->firstchild = p->firstchild;
delete p;
return true;
}
if(!b && !p->firstchild && !p->nextbrother)
{
f->firstchild = NULL;
delete p;
return true;
}
}
template <class T>
void Tree<T>::FirstRoot(CBNode<T> * t)
{
if(t)
{
cout<<t->data<<" ";
FirstRoot(t->firstchild);
FirstRoot(t->nextbrother);
}
}
template <class T>
void Tree<T>::LastRoot(CBNode<T> * t)
{
if(t)
{
LastRoot(t->firstchild);
cout<<t->data<<" ";
LastRoot(t->nextbrother);
}
}
template <class T>
void Tree<T>::LevelOrder()
{
queue<CBNode<T> *> Q;
CBNode<T> * p = NULL;
CBNode<T> * r = NULL;
if(!root)
{
cout<<"树为空"<<endl;
return ;
}
Q.push(root);
cout<<root->data<<" ";
while(!Q.empty())
{
r = Q.front();
Q.pop();
p = r->firstchild;
while(p)
{
Q.push(p);
cout<<p->data<<" ";
p = p->nextbrother;
}
}
}
template <class T>
void Tree<T>::Release(CBNode<T> * node)
{
if(node != NULL)
{
Release(node->firstchild);
Release(node->nextbrother);
delete node;
}
}
template <class T>
CBNode<T> * Tree<T>::search(T e,CBNode<T> * t)
{
if(!t)
return NULL;
if(t->data == e)
return t;
CBNode<T> * p;
p = search(e,t->firstchild);
if(p)
return p;
return search(e,t->nextbrother);
}
template <class T>
CBNode<T> * Tree<T>::searchparent(CBNode<T> * p)
{
queue<CBNode<T> *> Q;
CBNode<T> * q = NULL;
CBNode<T> * r = NULL;
if(p == root)
return NULL;
Q.push(root);
while(!Q.empty())
{
r = Q.front();
Q.pop();
if(r->firstchild == p)
return r;
q = r->firstchild;
while(q)
{
Q.push(q);
q->nextbrother;
}
}
return NULL;
}
template <class T>
CBNode<T> * Tree<T>::searchbrother(CBNode<T> * p)
{
queue<CBNode<T> *> Q;
CBNode<T> * q = NULL;
CBNode<T> * r = NULL;
if(p == root)
return NULL;
Q.push(root);
while(!Q.empty())
{
r = Q.front();
Q.pop();
q = r->firstchild;
while(q)
{
Q.push(q);
if(q->nextbrother == p)
return q;
q = q->nextbrother;
}
return NULL;
}
}
template <class T>
int Tree<T>::CountChild(CBNode<T> * t)
{
if(!t)
return 0;
int left = 0;
int right = 0;
left = CountChild(t->firstchild);
right = CountChild(t->nextbrother);
return 1+left+right;
}
template <class T>
int Tree<T>::Height(CBNode<T> * t)
{
CBNode<T> * p;
int h = 0;
int h1 = 0;
if(!t) return 0;
p = t->firstchild;
while(p)
{
h1 = Height(p);
if(h1>h)
h = h1;
p = p->nextbrother;
}
return h+1;
}
主函数测试
int main(int argc,char **argv)
{
Tree<int> T;
int n,f,s,r;
cout<<"请输入插入结点个数以及根节点"<<endl;
cin>>n>>s;
r = s;
T.InsertFirst(s);
for(int i = 0;i < n; i ++)
{
cout<<"请输入插入的第"<<i+1<<"个结点"<<endl;
cin>>f>>s;
T.Insert(f,s);
}
cout<<"先根遍历:";
T.FirstRoot();
cout<<endl;
cout<<"后根遍历:";
T.LastRoot();
cout<<endl;
cout<<"层次遍历:";
T.LevelOrder();
cout<<endl;
cin>>s;
T.Delete(s);
cout<<"先根遍历:";
T.FirstRoot();
cout<<endl;
cout<<"后根遍历:";
T.LastRoot();
cout<<endl;
cout<<"层次遍历:";
T.LevelOrder();
cout<<endl;
cout<<"结点数:"<<T.CountChild(r)<<endl;
cout<<"高度:"<<T.Height()<<endl;
return 0;
}