[樹] 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;
}