1. 程式人生 > >[樹] 6.66 雙親表示法PTree 轉 孩子兄弟表示式CSTree

[樹] 6.66 雙親表示法PTree 轉 孩子兄弟表示式CSTree

題目來源:嚴蔚敏《資料結構》C語言版本習題冊 6.66

【題目】6.66 假設有n個結點的樹T採用了雙親表示法,寫出由此建立樹的孩子-兄弟連結串列的演算法。

【答案】

/*---------------------------------
 |6.66 雙親表示法-->孩子兄弟表示式|
 ---------------------------------*/
#define MAX_TREE_SIZE 50

typedef struct PTNode{
	TElemType data;
	int parent; //雙親的位置域
}PTNode;
typedef struct{
	PTNode nodes[
MAX_TREE_SIZE]; int r,n; }PTree; CSTree CreateCSTreeByPTree(PTree T) { CSNode *tmp[MAX_TREE_SIZE]; //建立一個輔助的陣列,仿照PTree結點的位置存放 CSNode *p, *q; int i,parent; if (T.n<=0) return NULL; for (i=0; i<T.n; i++) { //雙親表按層序儲存 //建立新結點 p = (CSNode *)malloc(sizeof(CSNode)); if(!p) exit(OVERFLOW); //賦值 p->
data = T.nodes[i].data;p->firstchild=p->nextsibling=NULL; //連線 parent=T.nodes[i].parent; //父親 if (parent!=-1) { //不是根結點 if (tmp[parent]->firstchild==NULL) tmp[parent]->firstchild=p; //第一個孩子 else { //不是第一個孩子 for (q=tmp[parent]->firstchild; q->nextsibling; q=q->nextsibling) ;
//找到最後一個孩子 q->nextsibling = p; //連線 } } tmp[i]=p; } return tmp[0]; }

【完整程式碼】

/*-------------------
 |樹-孩子兄弟表達法 |
 -------------------*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#ifndef BASE
#define BASE
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int bool;
#endif

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



/*-------------------
 |6.59 輸出T的所有邊 |
 -------------------*/
void TreePrintEdge(CSTree T) {
	CSNode *p;
	for (p=T->firstchild; p; p=p->nextsibling) {
		printf("(%c,%c)\n", T->data, p->data); //輸出T的孩子
		TreePrintEdge(p); //輸出p的孩子
	}
}

/*-------------------------
 |6.60 統計葉子結點的個數 |
 -------------------------*/
int TreeLeafCnt(CSTree T) {
	// 樹的葉子結點-->沒有孩子
	int ret=0;
	CSNode *p;
	if (!T) return 0;
	else if (!T->firstchild) return 1;
	else {
		for (p=T->firstchild; p; p=p->nextsibling) ret += TreeLeafCnt(p);
		return ret;
	}
}


/*-------------------------
 |6.61 求樹的度           |
 -------------------------*/
int TreeDegree(CSTree T) {
	// 最大的孩子數
	int max=-1;
	int cnt=0;
	CSNode *child;
	if (!T) return -1; //空樹
	else if (!T->firstchild) return 0; //只有一個根結點,度為0
	else {
		for (cnt=0,child=T->firstchild; child; child=child->nextsibling) cnt++; //求自己的度
		max = cnt; //當前的最大值
		for (child=T->firstchild; child; child=child->nextsibling) {
			cnt = TreeDegree(child);
			if (cnt>max) max=cnt;
		}
		return max;
	}
}

/*-------------------------
 |6.62 求樹的深度         |
 -------------------------*/
int TreeDepth(CSTree T) {
	int h1,h2;
	if (!T) return 0;
	else {
		h1 = TreeDepth(T->firstchild)+1; //T孩子的深度+1
		h2 = TreeDepth(T->nextsibling); //T兄弟的深度
		return h1>h2 ? h1 : h2;
	}
}

/*---------------------------------
 |6.66 雙親表示法-->孩子兄弟表示式|
 ---------------------------------*/
#define MAX_TREE_SIZE 50

typedef struct PTNode{
	TElemType data;
	int parent; //雙親的位置域
}PTNode;
typedef struct{
	PTNode nodes[MAX_TREE_SIZE];
	int r,n;
}PTree;
CSTree CreateCSTreeByPTree(PTree T) {
	CSNode *tmp[MAX_TREE_SIZE]; //建立一個輔助的陣列,仿照PTree結點的位置存放
	CSNode *p, *q;
	int i,parent;
	
	if (T.n<=0) return NULL;
	for (i=0; i<T.n; i++) { //雙親表按層序儲存
		//建立新結點
		p = (CSNode *)malloc(sizeof(CSNode)); if(!p) exit(OVERFLOW);
		//賦值
		p->data = T.nodes[i].data;p->firstchild=p->nextsibling=NULL;
		//連線
		parent=T.nodes[i].parent; //父親
		if (parent!=-1) { //不是根結點
			if (tmp[parent]->firstchild==NULL) tmp[parent]->firstchild=p; //第一個孩子
			else { //不是第一個孩子
				for (q=tmp[parent]->firstchild; q->nextsibling; q=q->nextsibling) ; //找到最後一個孩子
				q->nextsibling = p; //連線
			}
		}
		tmp[i]=p;
	}
	
	return tmp[0];
}


int main() {
	PTree PT;
	CSTree CST;

	PT.n=10;PT.r=0;
	PT.nodes[0].data='R';PT.nodes[0].parent=-1;
	PT.nodes[1].data='A';PT.nodes[1].parent=0;
	PT.nodes[2].data='B';PT.nodes[2].parent=0;
	PT.nodes[3].data='C';PT.nodes[3].parent=0;
	PT.nodes[4].data='D';PT.nodes[4].parent=1;
	PT.nodes[5].data='E';PT.nodes[5].parent=1;
	PT.nodes[6].data='F';PT.nodes[6].parent=3;
	PT.nodes[7].data='G';PT.nodes[7].parent=6;
	PT.nodes[8].data='H';PT.nodes[8].parent=6;
	PT.nodes[9].data='I';PT.nodes[9].parent=6;

	CST = CreateCSTreeByPTree(PT);

	TreePrintEdge(CST);

	return 0;
}