深入淺出 二叉樹

2021-07-09 05:12:57 字數 3003 閱讀 5992

(題外話:)在資料結構和演算法中,資料結構也就是adt是組織資料的方式,而演算法就是解決問題的流程問題;通常我們說資料結構和演算法的優化就是兩個方面,即空間和時間,盡可能的使空間和時間最小化。基於以上兩個原則,才有了不斷在原來的經典的演算法之上繼續改進和創新。

本主今天講解一下二叉樹,二叉樹的應用很廣泛,尤其是在後面講解到查詢的演算法,二叉樹是乙個效率很高的資料結構,並且在此基礎上延伸到b數,b+樹,b*樹,紅黑樹等。

首先說一下什麼是樹? 樹作為乙個常用的資料結構,我們可以暫時理解為資料之間的一對多的關係如圖所示。

二叉樹在圖論中是這樣定義的:二叉樹是乙個連通的無環圖,並且每乙個頂點的度不大於3。有根二叉樹還要滿足根結點的度不大於2。有了根結點之後,每個頂點定義了唯一的父結點,和最多2個子結點。

可以把二叉樹的定義簡單得理解為:如存在根,每個節點的度不大於2,每個結點的孩子結點次序不能任意顛倒(遞迴定義)。

1.斜樹

所有結點都只有左子樹的二叉樹叫左斜樹,所有結點都只有右子樹的二叉樹叫右斜樹。斜樹的每一層都只有乙個結點,結點的個數與斜樹的深度相同。

2 滿二叉樹

在一棵二叉樹中,如果所有分支結點都存在左子樹和右子樹,並且所有葉子結點都在同一層上,這樣的二叉樹稱為滿二叉樹。(上圖中所示的二叉樹,就是一棵滿二叉樹)

3 完全二叉樹

對一棵具有n個結點的二叉樹按層序編號,如果編號為i(1≤i≤n)的結點與同樣深度的滿二叉樹中的編號為i的結點在二叉樹中的位置完全相同,則這棵二叉樹稱為完全二叉樹。

性質1:在二叉樹中至多有2^(n-1)個結點(n為樹的深度)。可用數學歸納法證明。

性質2:深度為k的二叉樹,至多有(2^n ) -1 個結點。

以上兩個性質常會在查詢樹等問題中用到,如求b樹的最小深度。

性質3:對任意乙個二叉樹,如終端結點n0,而度數為2的結點為n2,則有n0=n2+1。

證明:

設二叉樹的結點總數為n,度為0的結點即終端結點為n0,度為1的結點為n1,度為2的結點為n2,則有 n = n0 + n1 + n2,從另一方面講,度為1的結點有乙個子結點,度為2的結點有有兩個子結點,度為0的結點有0個子結點,則n = 0 * n0 + 1 * n1 + 2* n2 +1 ,這裡為什麼加1,加1 是由於加上根結點,由上面兩個公式可得 n0 = n2+1。

性質4:具有n個結點的完全二叉樹的深度為floor(log2n) + 1 。

性質5:如果對一棵有n個結點的完全二叉樹(其深度為floor(log2n) + 1)的結點按層序編號,則對任一結點i(1≤i≤n)有:

(1) 如果i = 1,則結點i是二叉樹的根,無雙親;如果i > 1,則其雙親parent(i)是結點 floor((i)/2)。

(2)如果2i > n,則結點i無左孩子;否則其左孩子lchild(i)是結點2i。

(3)如果2i + 1 > n,則結點i無右孩子;否則其右孩子rchild(i)是結點2i + 1。

由此性質可知,如果結點的編號為i(假設其左子樹、右子樹和父結點都存在),則其左子樹的編號為2i,右子樹的編號為2i +1, 其父節點為i/2。

二叉樹的邏輯結構如圖所示,是客觀世界的真實反映,反映了在客觀世界中資料之間組織的方式。如圖所示。

二叉樹的物理儲存結構即為在二叉樹在計算機世界的反映,一般是順序儲存和鏈式儲存。

順序儲存:如圖所示

由此可以看出,當二叉樹為左斜樹,右斜樹,會有很多的空間浪費。

鏈式儲存:如圖所示

由此可以看出,鏈式儲存雖然能夠節約空間,但是在查詢效率上回損失時間。因此,有二叉鍊錶拓展到三叉鍊錶,加個指向父節點的指標。提高查詢效率,由此可以看出,資料結構和演算法總是在空間和時間上尋求平衡,根據具體情況來設計資料結構和演算法。

#include "stdio.h"

#include "stdlib.h"

#include "string.h"

typedef char elemtype;

typedef int status; //狀態碼

#define error 0

#define true 1

/*定義二叉樹結構*/

typedef struct nodebtnode, *btree;

btree pre;

/*前序插入*/

void preorderinsert(btree *bt)

}/*前序遍歷*/

void

preorder

(btree t)

}/*中序遍歷*/

void

inorder

(btree t)

}/*後序遍歷*/

void

lastorder

(btree t)

}/*列印樹形結構*/

void

printtree

(btree bt, int nlayer)

printf

("%c\n",bt->data);

printtree

(bt->lchild,nlayer +1);

}/*樹的深度*/

intdepth

(btree bt)

else

return 0;

}void

main

()

深入淺出Spring(二)

ioc概念 控制反轉 inversion of control 是乙個重要的物件導向程式設計的法則來削減電腦程式的耦合問題。它還有乙個名字叫做依賴注入 dependency injection ioc 不是什麼技術,它是一種設計模式。例項演示 為了更好的說明 ioc,我為大家舉乙個簡單的例子,如有這...

深入淺出回歸樹演算法

之前的部落格 介紹了決策樹演算法在分類問題上面的應用,有提到id3演算法,c4.5演算法和cart演算法,其中cart classification and regression tree 分類回歸樹既可以用於分類,也可以用於回歸,當用於分類的時候,cart樹中每個葉子結點代表乙個類別,在回歸問題中...

深入淺出MySQL筆記(二)

本筆記為學習該書所記,便於複習。包含第三 四章筆記。資料型別與運算子 toc 整數型別 zerofill unsigned auto increment 浮點數型別 定點數型別 decimal m,d show warningsl 位型別bit m hex data datatime timesta...