1. 程式人生 > >[樹] 6.59-6.62 樹(孩子兄弟結點CSTree | 二叉樹儲存)的基本操作 -- 葉子結點個數|樹的度|樹的深度|列印樹的邊

[樹] 6.59-6.62 樹(孩子兄弟結點CSTree | 二叉樹儲存)的基本操作 -- 葉子結點個數|樹的度|樹的深度|列印樹的邊

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

【題目】6.59 編寫演算法完成下列操作:無重複地輸出以孩子-兄弟連結串列儲存的樹T中所有的邊。輸出的形式為(k1, k2), …, (ki, kj), …,其中,ki和kj為樹結點中的結點標識。 【題目】6.60 試編寫演算法,對一棵以孩子-兄弟連結串列表示的樹統計葉子的個數。 【題目】6.61 試編寫演算法,求一棵以孩子-兄弟連結串列表示的樹的度。 【題目】6.62 對以孩子-兄弟連結串列表示的樹編寫計算樹的深度的演算法

【答案】

/*-------------------
 |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; } }

【完整程式碼】 /------------------- |樹-孩子兄弟表達法 | -------------------/ #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的孩子 } }

/------------------------- |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§; 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; int cnt;

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); // 6.66  雙親表示法-->孩子兄弟表示式

TreePrintEdge(CST); // 6.59 以(F,C)輸出 

cnt = TreeLeafCnt(CST); //6.60 葉子結點個數
printf("TreeLeafCnt:%d\n", cnt);

cnt = TreeDegree(CST); //6.61 樹的度
printf("TreeDegree:%d\n", cnt);

cnt = TreeDepth(CST); //6.62 樹的深度
printf("TreeDepth:%d\n", cnt);

return 0;

}