1. 程式人生 > >【資料結構週週練】017 利用遞迴演算法及孩子兄弟表示法建立森林、遍歷森林並求森林的葉子結點個數

【資料結構週週練】017 利用遞迴演算法及孩子兄弟表示法建立森林、遍歷森林並求森林的葉子結點個數

 一、前言

從昨天起,就給大家分享一些樹和森林的程式碼啦,昨天分享的是求樹的深度,今天要給大家分享的是森林的遍歷以及求葉子的個數。

對於森林,大家可以做這樣的理解,一個深度大於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;
}

四、實現效果