求 以孩子-兄弟链表表示的树 的度、深度、叶结点和边

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Feynman1999/article/details/72771432

孩子兄弟表示法

任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟

//其结构可定义为
typedef struct CSNode{
	char data;
	struct CSNode* firstchild;
	struct CSNode* nextsibling;	
}CSNode,*CSTree;



上图中的树可以表示为:






一些算法的实现

一、对以孩子-兄弟链表表示的树编写计算树的的算法


二、对以孩子-兄弟链表表示的树编写计算树的深度的算法


三、试编写算法,对一颗以孩子-兄弟链表表示的树统计叶子的个数


四、编写算法完成下列操作:无重复地输出以孩子兄弟链表存储的树T中所有的。输出的形式为(k1,k2)……( ki, kj)……其中ki和kj为树结点中的结点标识



代码示例

#include<bits/stdc++.h>
#define OK 1
#define ERROR 0
using namespace std;

typedef struct CSNode{
	char data;
	struct CSNode* firstchild;
	struct CSNode* nextsibling;	
}CSNode,*CSTree;

//初始化 
void InitTree_CS(CSTree &T){
	T=NULL;
}

//接受前序扩展序列建树 
int CreateTree_CS(CSTree &T){
	char ch;
	scanf("%c",&ch);
	if(ch=='^'){
		T=NULL;
	}
	else{
		T=(CSTree)malloc(sizeof(CSNode));
		if(!T) exit(0);
		T->data=ch;
		CreateTree_CS(T->firstchild);
		CreateTree_CS(T->nextsibling);
	}
	return OK;
}


 
//树的度 
int Algo_1(CSTree T){
	int i,j,max,tmp;
	CSTree Q[100];//临时存放各结点 
	i=j=0;
	max=-1;
	if(T)
	{
		max=0;
		Q[j++]=T->firstchild;
		
		while(i<j)//按层序遍历 
		{
			tmp=0;
			while(Q[i])
			{
				tmp++;
				//存储有孩子的结点 
				if(Q[i]->firstchild) Q[j++]=Q[i]->firstchild;
				Q[i]=Q[i]->nextsibling;//统计本层结点数 
			}
			if(tmp>max) max=tmp;
			i++;
		}
	}
	return max;
} 


//树的深度
int Algo_2(CSTree T){
	int row,max;
	stack<CSTree> S;
	CSTree tmp;
	row=0;
	if(T)
	{
		S.push(T);
		row=max=1;
		
		while(!S.empty())
		{
			tmp=S.top();
			while(tmp->firstchild)
			{
				S.push(tmp->firstchild);
				++max;
				if(row<max) row=max;
				tmp=S.top();
			}
			tmp=S.top();
			S.pop();
			if(tmp->nextsibling)
				S.push(tmp->nextsibling);
			else{
				while(!S.empty())
				{
					tmp=S.top();
					S.pop();
					--max;
					
					if(tmp->nextsibling){
						S.push(tmp->nextsibling);
						break;
					}
				}
			}
		}
	}
	return row;
}


//树的叶子 
int Algo_3(CSTree T){
	if(T)
	{
		if(!T->firstchild){
		cout<<T->data<<' ';//输出叶子结点 
		return 1+Algo_3(T->nextsibling);
		}
		else return Algo_3(T->firstchild)+Algo_3(T->nextsibling);
	}
	else return 0;
}


//树的边
void Algo_4(CSTree T){
	CSTree p,q;
	if(T)
	{
		p=T;
		q=T->firstchild;
		int i=0;//打印计数器 
		while(q)
		{
			printf("(%c,%c) ",p->data,q->data);
			q=q->nextsibling;
			i++;
		}
		if(i>0) cout<<endl;
		Algo_4(T->firstchild);
		Algo_4(T->nextsibling);
	}
}


int main()
{
	CSTree T;
	InitTree_CS(T);
	printf("请录入先序序列(扩展法、前序): 例如:RAD^E^^B^CFG^H^K^^^^^\n");
	CreateTree_CS(T);
	
	
	cout<<"****度****"<<endl; 
	cout<<"树的度(结点的最大度)为:"<<Algo_1(T)<<endl<<endl<<endl;
	
	
	cout<<"****深度****"<<endl;
	cout<<"树的深度为:"<<Algo_2(T)<<endl<<endl<<endl;
	
	
	cout<<"****叶子****"<<endl; 
	cout<<"叶子结点分别为:"<<endl;
	cout<<"个数为:"<<Algo_3(T)<<endl<<endl<<endl;
	
	
	cout<<"****边****"<<endl;
	cout<<"下面输出所有边:"<<endl;
	Algo_4(T);
	cout<<endl;
	return 0;
} 



运行结果







展开阅读全文

没有更多推荐了,返回首页