圖1-完全二叉樹
二叉樹的順序儲存結構是按照編號次序儲存節點,即對樹中每個節點進行編號,其編號從小到大的順序就是節點在連續儲存單元的先後次序
。
圖2- 二叉樹的順序儲存結構
當我們採用順序儲存結構去儲存乙個節點時可以根據二叉樹的性質去求該節點的左孩子和右孩子節點,以及雙親節點:
1. 若編號為i的節點的左孩子節點的編號為2i;右孩子節點的編號為(2i+1)。
2. 除樹根節點外,若乙個節點的編號為i,則它的雙親節點的編號為[ i/2 ]。
圖3-一般二叉樹
上面講的是完全二叉樹的儲存,但是在應用中完全二叉樹是乙個特例,更多的是考慮一般的二叉樹的儲存結構。而對於一般二叉樹的結構先採用空節點補全成為完全二叉樹,但是這並不是說我們要真的補全,補全的目的只是為了方便編號,確定儲存結構,但是我們並不關心補全的節點
。
當把一般二叉樹進行補全為完全二叉樹後,再對節點編號,最後確定了儲存結構,下面給出一般二叉樹補全後的儲存結構:
圖4-一般二叉樹的儲存結構
在圖4中凡是#符號代替的都是補全的節點,且下標為0的位置一般都不儲存任何有效資料
。對於編號為2的節點來說,它的左孩子節點為空,所以用編號為4的節點進行補全。對於編號為3的節點來說,它的左孩子節點也是為空,因此用編號為6的節點進行補全,其他補全的節點以此類推……
對於這樣的儲存結構,我們用程式語言來定義儲存結構,如下所示:
#define maxsize 15
typedef elemtype sqbtree[maxsize];
sqbtree bt="#abd#c#e######f";
bt[i]的子女節點:bt[2
*i] , bt[2
*i+1]
bt[i]的雙親節點:bt[[ i/2 ] ]
不知道大家是否發現沒,其實這樣的儲存結構有乙個問題,那就是真正儲存節點資料的儲存單元並不多,出現了大量的浪費,而圖4中至少有一半以上的儲存空間沒有儲存資料,對於儲存空間的利用率嚴重不足,因此順序儲存結構適用於完全二叉樹,並不適用於一般的二叉樹,而對於一般的二叉樹來說,有更好的儲存方案,有小夥伴猜到了,沒錯,就是接下來要介紹的鏈式儲存結構
。
圖5在工程應用中,對於二叉樹的儲存結構更多的是採用鏈式儲存結構,而二叉樹的鏈式儲存結構中,對於每個節點我們不要要儲存節點本身,還要儲存該節點的左孩子節點和右孩子節點,因此這裡我們直接使用程式語言來定義二叉樹的鏈式儲存結構,如下所示:
typedef
struct node
btnode;
在這樣的儲存結構中我們發現,data表示值域,用於儲存對應的節點資料元素,lchild和rchild分別表示左指標域和右指標域,用於分別儲存左孩子節點和右孩子節點(即左、右子樹的根節點)的儲存位置。
那麼圖5中的二叉樹對應的儲存結構就是如圖6所示,而後面我們要針對二叉樹進行一些基本運算也是基於這樣的鏈式儲存結構:
圖6-二叉樹的鏈式儲存結構
我們發現二叉樹的鏈式儲存結構彌補了順序儲存結構的一些缺點:不需要考慮補齊節點的問題,也不會出現儲存空間浪費的問題,無論是完全二叉樹,滿二叉樹,還是一般二叉樹都適用於這種儲存方案。
到這裡,對於樹結構的一些基本概念,基本性質,術語等總算是告一段落了,這些內容比較繁雜,需要花一些時間理解,總結。現在我們暫且枕戈待旦,之後再開啟新的篇章。
二叉樹的儲存結構
二叉樹是非線性結構,即每個資料結點至多只有乙個前驅,但可以有多個後繼。它可採用順序儲存結構和鏈式儲存結構。1 順序儲存結構 二叉樹的順序儲存,就是用一組連續的儲存單元存放二叉樹中的結點。因此,必須把二叉樹的所有結點安排成為乙個恰當的序列,結點在這個序列中的相互位置能反映出結點之間的邏輯關係,用編號的...
二叉樹的儲存結構
二叉樹是非線性結構,即每個資料結點至多只有乙個前驅,但可以有多個後繼。它可採用順序儲存結構和鏈式儲存結構。1 順序儲存結構 二叉樹的順序儲存,就是用一組連續的儲存單元存放二叉樹中的結點。因此,必須把二叉樹的所有結點安排成為乙個恰當的序列,結點在這個序列中的相互位置能反映出結點之間的邏輯關係,用編號的...
二叉樹的儲存結構
二叉樹是非線性結構,即每個資料結點至多只有乙個前驅,但可以有多個後繼。它可採用順序儲存結構和鏈式儲存結構。1 順序儲存結構 二叉樹的順序儲存,就是用一組連續的儲存單元存放二叉樹中的結點。因此,必須把二叉樹的所有結點安排成為乙個恰當的序列,結點在這個序列中的相互位置能反映出結點之間的邏輯關係,用編號的...