1. 程式人生 > >二叉樹的構建與遍歷(連結串列法)

二叉樹的構建與遍歷(連結串列法)

二叉樹作為基礎資料結構,其構建與遍歷可以說是一名程式設計師的基本功,更是一名ACMer的應爛熟於心的知識。

其中建立二叉樹的方法主要有用連結串列建立和用陣列建立,本篇文章我們先來介紹連結串列法建立二叉樹。

相對於用陣列建立二叉樹來說,用連結串列建立二叉樹具有節省空間,簡介明瞭、直觀的特點,因此在大部分情況下推薦使用連結串列法建樹。但如果查詢樹上的一個節點,陣列法就比較簡介,兩種方法各有千秋,文無定法,適者為尊。

對於遍歷來說,樹的遍歷基本有三種,為先序遍歷(根左右),中序遍歷(左根右),後序遍歷(左右根)。當我們建好樹後,以上三種遍歷都可以用遞迴方法實現,實現較為簡單,非程式設計初學者看程式碼即可領悟,這裡不在贅述。

我們以一道題為例,來講解二叉樹的構建與遍歷。

【問題描述】

根據輸入提示,構建二叉樹。本題目中,對所有節點進行編號 【輸入形式】

第一行整數m,表示二叉樹中共有m個非空節點 

第二行m個整數,表示編號節點對應的value值,編號從1到m 後面一共m行,表示編號節點的左右子節點編號,0表示對應位置的子節點不存在 

【輸出形式】

按先序輸出格式輸出二叉樹 【樣例輸入】 8 10 4 3 9 2 5 6 7 1 2 3 2 0 4 3 5 6 4 7 0 5 0 0 6 0 8 7 0 0 8 0 0

【樣例輸出】

10 4 9 6 3 2 5 7

分析:

本題就是一道考察建樹及遍歷的基礎題,無任何其他內容。

解析:

用連結串列建樹,首先需掌握基本連結串列操作,這裡所指連結串列並非是C++中STL自帶容器,本人一貫認為STL雖然可以減少很多工作量,但對於初學者來說,自己手寫程式碼是個很重要的過程,在之前的OI比賽中(近期情況並不瞭解),STL庫函式是禁用的。所以對基礎知識不熟者,需自行查書或自行百度。

其實建樹並沒有什麼可講的,不涉及演算法,下面我就用加註釋的方法解釋建樹和遍歷的過程,大家在理解後可自行整理為屬於自己風格的模板,留作自己的東西

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
struct Btree{
	int num;                    //節點編號
	struct Btree *Lchild;    //左子樹
	struct Btree *Rchild;   //右子樹
};
struct data{
	int left;                  //左孩子節點編號
	int right;                //右孩子節點編號
};
int value[110];                  //節點的值
data tree[110];                  //用作儲存讀入
Btree *CreateTree(int root)
{
	Btree *t;                                    
	t = (Btree*) malloc (sizeof(Btree));  // 申請新節點空間
	t->num = root;                        //編號賦值
	if(tree[root].left == 0) t->Lchild=NULL;
	else t->Lchild = CreateTree(tree[root].left);   //去建左子樹
 	if(tree[root].right == 0) t->Rchild=NULL;
 	else t->Rchild = CreateTree(tree[root].right);  //去建右子樹
 	return t;
}
void pre(Btree *&t)
{
	if(t)
	{
		printf("%d ",value[t->num]);  //根
		pre(t->Lchild);      //左
		pre(t->Rchild);     //右
	}
}
void middle(Btree *&t)
{
	if(t)
	{
		middle(t->Lchild);
		printf("%d ",value[t->num]);
		middle(t->Rchild);
	}
}
void back(Btree *&t)
{
	if(t)
	{
		back(t->Lchild);
		back(t->Rchild);
		printf("%d ",value[t->num]);
	}
}
int main()
{
	int m;
	scanf("%d",&m);
	for(int i = 1;i <= m;i++)
		scanf("%d",&value[i]);
	for(int i = 1;i <= m;i++)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		tree[a].left = b;tree[a].right = c;  
	}
	Btree *t;			//建樹
	//t = (Btree *) malloc (sizeof(Btree)) 
	t = CreateTree(1);            //樹根
	pre(t);printf("\n");
	middle(t);printf("\n");
	back(t);printf("\n");
}