孩子兄弟树

数据结构

孩子兄弟树是一种常见的树结构,与二叉树不同,他能够允许一个父结点拥有多个子结点。其结点的格式为:第一个孩子结点指针,指向下一个兄弟的指针以及数据域。
结点结构
对于如下一颗孩子兄弟树
在这里插入图片描述其真实的链接方式为
在这里插入图片描述孩子兄弟树和二叉树同样通过递归来实现遍历
先根遍历: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;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值