【資料結構】資料的儲存結構
資料有有線性結構、樹形結構、圖狀結構和集合四種邏輯結構,那麼它們是如何儲存的呢?
資料結構的儲存結構有兩種,分別是順序儲存和鏈式儲存。順序儲存的特點是藉助元素在儲存器中的相對位置來表示資料元素之間的邏輯關係;鏈式儲存的特點是藉助指標表示資料元素質檢單邏輯關係。
1.線性結構:結構中的元素之間存在著一對一的線性關係。
如圖為一個線性結構,那麼它的順序儲存和鏈式儲存如何呢?如下圖:
順序結構 鏈式結構
線性結構如陣列的存法,按一定順序存放;而鏈式結構如連結串列的存法,結點可以任意存放,如上圖,所以要用next相連,以保證每一個結點都有唯一確定的前驅和後繼。
2.樹形結構:結構中的資料元素之間存在著一對一的線性關係。(這裡我們以二叉樹為例)
如圖是一個簡單的二叉樹,其中6號結點不存在,其順序儲存如下圖:
因為是二叉樹,所以我們可以認為每個結點都有兩個“孩子”,不存在的可以用“空”來表示(上圖中的6號就是空),這樣就可以用一行表示一個完整的二叉樹,並且知道每一個結點所對應的前驅和後繼。
至此我們就可以發現:
2,3對應的前驅是1;
4,5對應的前驅是2;
6,7對應的前驅是3。
這樣我們就可以推匯出幾個關係:
若結點為i,則i的前驅是i/2;i的左後繼是2i;i的右後繼是2i+1。
下面再給大家一個例子供參考(其中符號∧代表空,也可用null表示):
那麼二叉樹的鏈式結構又如何呢?
二叉樹的結點結構如下圖:
LChild域指向該結點的左孩子,Data域記錄該結點的資料,RChild域指向該結點的右孩子。二叉樹的鏈式結構儲存如下圖所示:
我們可以讓頭指標指向A,則二叉連結串列結點結構的描述如下:
typedef struct Node
{
DataType date;
Struct Node *Lchild;
Struct Node *Rchild;
}BiTNode, *BiTree;
為了方便訪問某結點的雙親,還可以給連結串列結點增加一個雙親欄位parent,用來指向其雙親結點。每個結點由四個域組成,其結點結構為:
在實際應用中,要根據二叉樹的形態和具體要進行的操作來選擇決定採用哪種儲存結構。
3.圖狀結構:結構中的資料元素之間存在著多對多的任意關係。
以無向圖為例,如下圖所示:
則可得出關係為:
A: (A,B) (A,C)
B:(B,A) (B,C) (B,D)
C:(C,A) (C,B) (C,D)
D: (D,B) (D,C)
以陣列的儲存方式(鄰接矩陣)進行儲存可得:
其中“1”代表存在關係,“0”代表不存在關係。
將其轉化為鏈式的形式如下圖:
對其鏈式結構我們可採用指標陣列(鄰接表)的方式來連線單鏈表,其中的字母應換成相應的陣列下標,如下圖:
鄰接矩陣是不錯的一種圖儲存結構,但是,對於邊數相對頂點較少的圖,這種結構存在對儲存空間的極大浪費。因此,找到一種陣列與連結串列相結合的儲存方法稱為鄰接表。圖中每個頂點的所有鄰接點構成一個線性表,由於鄰接點的個數不定,所以,用單鏈表儲存,無向圖稱為頂點的邊表,有向圖則稱為頂點作為弧尾的出邊表。
有向圖情況類似,大家可以自己試一試。而在有向圖中,對於帶權值的網圖,可以在邊表結點定義中再增加一個數據域,儲存權值資訊即可。如下圖: