1. 程式人生 > >二叉樹(建立、遍歷、樹的最大深度和最小深度)

二叉樹(建立、遍歷、樹的最大深度和最小深度)

樹的引出最初是由二分查詢的原理引出來的,一般順序查詢演算法的複雜度為O(N),而一般二分查詢的複雜度為logN
一個二分查詢演算法可以用一顆查詢樹來表示,樹的根結點為順序陣列的中點,這樣依次查詢效率等同於二分查詢演算法
一般的樹用陣列表示或連結串列表示都會造成空間的浪費,而由於一般的樹可以通過兄弟兒子表示法將一般樹轉換為二叉樹
因此對樹的研究主要針對是針對二叉樹的研究
二叉樹可以分為一般二叉樹,完全二叉樹和完美二叉樹
1 二叉樹的儲存:
陣列:
這需要將二叉樹填充為完全二叉樹,並按編號儲存在陣列中,並根據編號左孩子=父節點*2,右孩子=父節點*2+1,父節點=[子節點/2]的確定層次關係
而這對於非完全二叉樹會造成一定的資源浪費
連結串列:
一個節點包含一個數據和一個左指標和右指標,依然會有一些浪費

2 二叉樹的遍歷:先序/中序/後序----遍歷的核心問題為:二維結構的線性化
遞迴:
方法較簡單,其實遞迴的實現是依靠棧
如中序遍歷:
(1)中序遍歷其左子樹
(2)訪問根節點
(3)中序遍歷其右子樹

結論:以上三種遍歷方法都有一個連通的遍歷路徑,三種遍歷過程經過的路線一樣,只是訪問節點的時機不同,由此引出堆疊實現遍歷的方法:
堆疊:
如中序遍歷的堆疊實現方法:
--遇到一個節點,就把它壓棧,並去遍歷它的左子樹;
--當左子樹遍歷結束後,從棧頂彈出一個結點,並訪問它
--然後按照這個節點的右指標再去中序遍歷該節點的右子樹。
其他遍歷方法類似
具體程式碼參考網上

接下來我們利用連結串列來實現一個二叉樹,其實一般的二叉樹用處並不大,後面會引申出二叉搜尋樹,紅黑樹,堆等。。再此我們只需要掌握如何對二叉樹進行遍歷,首先我們用前序遍歷的方法建立一個二叉樹,然後研究其遍歷方法(遞迴),只給出了中序遍歷,其他遍歷方法類似,交換一下順序即可。

另外,還需要了解一些其他對樹的操作,再此舉一個《劍指offer》上的一個筆試題,即給出一個樹,求出樹的最大深度和最小深度。

#include <iostream>
using namespace std;
typedef char elemtype;
typedef struct TreeNode{
	elemtype val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(elemtype x) : val(x),left(NULL),right(NULL){}
}Node, *Tree;
Tree creatTree()
{
	elemtype x;
	Node *node;
	cin >> x;
	if(x == -1) 
		node = NULL;
	else
	{
		node = new Node(x);
		node->left = creatTree();
		node->right = creatTree();
	}
	return node;
}
int maxDepth(Tree T)
{
	int DL, DR, Dmax;
	if(T)
	{
		DL = maxDepth(T->left);
		DR = maxDepth(T->right);
		Dmax = (DL<DR)?DR : DL;
		return (Dmax+1);
	}
	else
		return 0;
}

int minDepth(Tree T)
{
	int DL, DR, Dmin;
	if(T)
	{
		if(T->left == NULL) return minDepth(T->right) + 1;
      if(T->right == NULL) return minDepth(T->left) + 1;
		DL = minDepth(T->left);
		DR = minDepth(T->right);
		Dmin = (DL>DR)?DR : DL;
		return (Dmin+1);
	}
	else
		return 0;
	
}
void inorderTraverse(Tree T)
{
	if(T)
	{
		cout << T->val << " ";
		inorderTraverse(T->left);
		inorderTraverse(T->right);
	}
}
int main()
{
	Tree tree;
	tree = creatTree();
	inorderTraverse(tree);
	cout << endl;
	cout << "minDepth:" << minDepth(tree) << endl;
	cout << "maxDepth:" << maxDepth(tree) << endl;
	return 0;
}