1. 程式人生 > >【資料結構週週練】010 遞迴演算法實現二叉樹的建立與遍歷

【資料結構週週練】010 遞迴演算法實現二叉樹的建立與遍歷

一、前言

上兩篇週週練部落格講了二叉樹的建立與遍歷,建立時,通過建立棧來存放結點,方便二叉樹的建立,這種建立二叉樹的方式採用了非遞迴演算法,本次內容採用遞迴的方式來建立二叉樹,大家可以通過對比程式碼量,感受一下遞迴的魅力。同時遍歷過程也是通過遞迴演算法。

如果大家第一次看我的部落格是這一篇,這裡給大家連結,方便大家瞭解非遞迴二叉樹遍歷及三種遍歷方式的理解方式。

重點部分

遞迴二叉樹建立過程,無需創立一個棧空間,同樣也比較不容易一步獲取雙親結點,棧空間直接從棧頂獲取即可,那我們就要根據遞迴的原理,來建立一個結點儲存雙親結點,具體我會在程式碼中體現。

這次程式碼無需使用者輸入,執行就能直接出結果。我將所有需要輸入的地方全部轉化為陣列元素存到陣列中,通過呼叫陣列自動賦值。自動建立。

二、題目

將下圖用二叉樹存入,並通過三種遍歷方式對該樹進行遍歷。其中圓角矩形內為結點資料,旁邊數字為結點編號,編號為0的結點為根節點,箭頭指向的結點為箭尾的孩子結點。要求遍歷每個結點時能夠查詢當前結點的資料、編號、雙親結點以及孩子結點的編號,如果結點是根節點或者葉子結點,請說明。

 三、程式碼

#include<iostream>
#include<malloc.h>

using namespace std;

typedef struct BiTNode {
		int data;
		int number;
		int isAsk;
		struct BiTNode *parent,* lChild, * rChild;
	}BiTNode,*BiTree;

int number = 0;
int yon = 0;
int yesOrNo[] = { 1,0,1,0,0,1,1,1,0,0,1,0,0,1,0,0 };
int numData[] = { 12,31,25,67,80,51,77,32 };
BiTree treeParent = NULL;

int OperationBiTree(BiTree &BT) {
	BT = (BiTree)malloc(sizeof(BiTNode));
	if (!BT)
	{
		cout << "空間分配失敗" << endl;
		exit(OVERFLOW);
	}
	BT->number = number;
	number++;
	BT->data = numData[BT->number];
	BT->lChild = NULL;
	BT->rChild = NULL;
	BT->parent = treeParent;
	return 1;
}

void PreOrderCreatBiTree(BiTree &BT) {
	
	OperationBiTree(BT);
	treeParent = BT;
	if (yesOrNo[yon++])
		PreOrderCreatBiTree(BT->lChild);
	treeParent = BT;
	if (yesOrNo[yon++])
		PreOrderCreatBiTree(BT->rChild);

}

void VisitBiTree(BiTree BT) {
	cout << "當前結點的編號為:" << BT->number<<", ";
	cout << "資料為:" << BT->data << ",\n";
	if (BT->parent)
		cout << "    當前結點有雙親結點,結點編號為:" << BT->parent->number << ",\n";
	else
		cout << "    當前結點為根節點,無雙親結點\n";
	if (BT->lChild)
		cout << "    當前結點有左孩子結點,結點編號為:" << BT->lChild->number << ",\n";
	if (BT->rChild)
		cout << "    當前結點有右孩子結點,結點編號為:" << BT->rChild->number << ",\n";
	if (!BT->lChild && !BT->rChild)
		cout << "    當前結點為葉子結點\n";
	cout << endl;
	
}

void PreOrderBiTree(BiTree BT) {
	if (BT)
	{
		VisitBiTree(BT);
		PreOrderBiTree(BT->lChild);
		PreOrderBiTree(BT->rChild);
	}
}

void InOrderBiTree(BiTree BT) {
	if (BT)
	{
		InOrderBiTree(BT->lChild);
		VisitBiTree(BT);
		InOrderBiTree(BT->rChild);
	}
}

void PostOrderBiTree(BiTree BT) {
	if (BT)
	{
		PostOrderBiTree(BT->lChild);
		PostOrderBiTree(BT->rChild);
		VisitBiTree(BT);
	}
}

void main() {
	BiTree BT;
	PreOrderCreatBiTree(BT);
	cout << "\n**********************遍歷二叉樹開始**********************\n" ;
	cout << "\n**********************先序遍歷二叉樹**********************\n";
	PreOrderBiTree(BT);
	cout << "\n**********************中序遍歷二叉樹**********************\n";
	InOrderBiTree(BT);
	cout << "\n**********************後序遍歷二叉樹**********************\n";
	PostOrderBiTree(BT);

}

四、實現效果