树的表示(2)--子女兄弟表示法

头结点:

struct Node
{
	char data;
	struct Node* lchild, *rsibling;
};

1、建树:
通过给定树的层次序列所有元素以及对应结点的度来构造树。例如这样一课树:

R
     A
          D
          E
     B
     C
          F
               G
               H
               K

它的层次遍历为:RABCDEFGHK
对应结点的度为:
3 ,2 ,0 ,1 ,0 ,0 ,3 ,0 ,0 ,0
建树的算法思路:
先建立n个树结点,给他们赋值并将指针初始化;然后扫描结点的度,按度数d取紧接着的d个结点的元素值建立d叉树。这都依赖于层次次序排列的特点。

void createChildAndSiblingTree(Node *&root, string e, vector<int> degree)
{//根据树结点的层次序列e和各结点的度degree构造树的子女兄弟链表
	if (e.length() == 0)				//空树 
	{
		root = NULL;
		return;
	}
	Node **Q = new Node*[e.length()];	//辅助数组,用于存放树结点的地址 
	for (int i = 0; i < e.length(); i++)		//初始化所有的树结点 
	{
		Q[i] = new Node();
		Q[i]->data = e[i];
		Q[i]->lchild = Q[i]->rsibling = NULL;
	}
	int k = 0;			// 
	for (int i = 0; i < e.length(); i++)	//扫描所有结点 
	{
		int d = degree[i];
		if (d > 0)				//度大于0,有子树 
		{
			k++;
			Q[i]->lchild = Q[k];		//紧随的元素为第一个子女 
			while (--d > 0)				//后续的子女存到兄弟链中 
			{
				Q[k]->rsibling = Q[k + 1];
				k++;
			}
		}
	}
	root = Q[0];		//根存在Q[0]所指的结点 
	delete Q;
}

2、打印:

void printChildAndSiblingTree(Node *root, int k)
{
	if (root != NULL)
	{
		for (int i = 0; i < k; i++) cout << " ";		//	右移k个字符 
		cout << root->data << endl;						//输出根结点data 
		for (Node * p = root->lchild; p != NULL; p = p->rsibling)	
		{
			printChildAndSiblingTree(p, k + 5);			//输出根的子树 
		}
	}
}

3、获取某个结点的双亲

Node* getParent(Node* root,Node *p)
{
	Node *s,*q;			
	for(q = root->lchild; q != NULL; q = q->rsibling)
	{
		if(q == p)  return root;			//若子女为*p,则双亲为*root 
		if((s = getParent(q,p)) != NULL)   return s;		//递归到子树q中找*p的双亲 
	}
	return NULL;		//该树(子树)无双亲 
}

4、全部代码:

#include<iostream>
#include<string> 
#include<vector>

using namespace std;

struct Node
{
	char data;
	struct Node* lchild, *rsibling;
};

void createChildAndSiblingTree(Node *&root, string e, vector<int> degree)
{//根据树结点的层次序列e和各结点的度degree构造树的子女兄弟链表
	if (e.length() == 0)				//空树 
	{
		root = NULL;
		return;
	}
	Node **Q = new Node*[e.length()];	//辅助数组,用于存放树结点的地址 
	for (int i = 0; i < e.length(); i++)		//初始化所有的树结点 
	{
		Q[i] = new Node();
		Q[i]->data = e[i];
		Q[i]->lchild = Q[i]->rsibling = NULL;
	}
	int k = 0;			// 
	for (int i = 0; i < e.length(); i++)	//扫描所有结点 
	{
		int d = degree[i];
		if (d > 0)				//度大于0,有子树 
		{
			k++;
			Q[i]->lchild = Q[k];		//紧随的元素为第一个子女 
			while (--d > 0)				//后续的子女存到兄弟链中 
			{
				Q[k]->rsibling = Q[k + 1];
				k++;
			}
		}
	}
	root = Q[0];		//根存在Q[0]所指的结点 
	delete Q;
}
void printChildAndSiblingTree(Node *root, int k)
{
	if (root != NULL)
	{
		for (int i = 0; i < k; i++) cout << " ";		//	右移k个字符 
		cout << root->data << endl;						//输出根结点data 
		for (Node * p = root->lchild; p != NULL; p = p->rsibling)	
		{
			printChildAndSiblingTree(p, k + 5);			//输出根的子树 
		}
	}
}
Node* getParent(Node* root,Node *p)
{
	Node *s,*q;			
	for(q = root->lchild; q != NULL; q = q->rsibling)
	{
		if(q == p)  return root;			//若子女为*p,则双亲为*root 
		if((s = getParent(q,p)) != NULL)   return s;		//递归到子树q中找*p的双亲 
	}
	return NULL;		//该树(子树)无双亲 
}
int main()
{
	string e = "RABCDEFGHK";
	vector<int> degree= { 3,2,0,1,0,0,3,0,0,0 };
	Node *root = NULL;
	createChildAndSiblingTree(root, e, degree);
	printChildAndSiblingTree(root, 0);
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值