【資料結構週週練】017 利用遞迴演算法及孩子兄弟表示法建立森林、遍歷森林並求森林的葉子結點個數
阿新 • • 發佈:2018-12-17
一、前言
從昨天起,就給大家分享一些樹和森林的程式碼啦,昨天分享的是求樹的深度,今天要給大家分享的是森林的遍歷以及求葉子的個數。
對於森林,大家可以做這樣的理解,一個深度大於1,根節點子樹個數大於1的樹去掉根節點,就是森林。森林中每棵樹的根節點再建立一個共同的雙親結點,就成為了一棵樹。所以森林轉化為二叉樹和樹轉化為二叉樹原理是一樣的,採用的方法依然是孩子兄弟表示法,轉化規律如下:
森林中第一顆樹的根作為生成二叉樹的根,每個結點左指標指向第一個孩子結點,右指標指向它在森林中的相鄰兄弟結點。通過這種方法構造的二叉樹至少包括資料域,第一個孩子指標和右兄弟指標。
typedef struct CSNode { int data; struct CSNode *firstChild, *nextSibling; }CSNode, *CSTree;
二、題目
利用遞迴演算法及孩子兄弟表示法存入下圖的森林,遍歷訪問每個結點的編號,資料及所有的兄弟及孩子結點。其中圓角矩形內為結點資料,旁邊數字為結點編號,箭頭指向的結點為箭尾的孩子結點。
三、程式碼
#include<iostream> #include<malloc.h> using namespace std; typedef struct CSNode { int data; int number; struct CSNode *firstChild, *nextSibling; }CSNode,*CSTree; int number = 0; int yon = 0; int yesOrNo[] = { 1,1,0,1,1,0,0,0,1,0,0,1,1,0,1,1,0,0,0,1,1,0,0,1,0,0 }; int numData[] = { 1,2,4,5,6,3,7,8,9,10,11,12,13 }; int leafNumber = 0; //Operation the node to creat the forest int OperationNode(CSTree &T) { T = (CSTree)malloc(sizeof(CSNode)); if (!T) { cout << "空間分配失敗(Allocate space failure.)" << endl; exit(OVERFLOW); } T->data = numData[number]; T->number = number; number++; T->firstChild = NULL; T->nextSibling = NULL; return 1; } //Eatablish the fotest by the method of child and sibling void EstablishTree(CSTree &T) { OperationNode(T); if (yesOrNo[yon++]) EstablishTree(T->firstChild); if (yesOrNo[yon++]) EstablishTree(T->nextSibling); } void VisitForest(CSTree T) { CSTree p = T; cout << "【" << p->number + 1 << "】The number of present node is :" << p->number << ","; cout << "and the data is :" << p->data << "."; if (p->nextSibling) { cout << "\n\tThis node has sibling and the number is :" << p->nextSibling->number; p = p->nextSibling; while (p->nextSibling) { cout << " , " << p->nextSibling->number; p = p->nextSibling; } } if (T->firstChild) { cout << "\n\tThis node has child and the number is :" << T->firstChild->number; CSTree q = T->firstChild; while (q->nextSibling) { cout << " , " << q->nextSibling->number; q = q->nextSibling; } } cout << endl << endl; } void PreOrderVisitForest(CSTree T) { VisitForest(T); if (T->firstChild) PreOrderVisitForest(T->firstChild); else leafNumber++; if (T->nextSibling) PreOrderVisitForest(T->nextSibling); } void main() { CSTree T; cout << "********【遍歷剛剛建立的森林。Traverse forest just establish】********" << endl; EstablishTree(T); PreOrderVisitForest(T); cout << "The number of leaf of Forest is : " << leafNumber << endl; }