線性表的鏈式儲存結構
1、線性錶鏈式儲存結構定義
先看個圖
線性表的鏈式儲存結構的特點是用一組任意的儲存單元儲存線性表的資料元素,這組儲存單元可以是連續的,也可以是不連續的。這就意味著,這些資料元素可以存在記憶體未被佔用的任意位置。
以前的順序儲存結構中,每個資料元素只需要儲存資料元素就可以了。現在鏈式結構中,處理要儲存資料元素資訊之外,還要儲存它的後繼元素的儲存地址。
為了表示每個元素ai與其直接後繼元素ai+1之間的邏輯關係,對資料元素ai來說,除了儲存其本身的資訊之外,還需要儲存一個指示其直接後繼的資訊(即直接後繼的儲存位置)。把儲存資料元素的域稱為資料域,把儲存直接後繼位置的域稱為指標域。指標域中儲存的資訊稱作指標或鏈。這兩部分資訊組成資料元素ai的儲存映像,稱為結點。
n個結點鏈結成一個連結串列,即為線性表(a1,a2,a3...an)的;鏈式儲存結構,因為此連結串列的每個結點中只包含一個指標域,所以叫做單連結串列。
連結串列的第一個結點儲存位置叫做頭指標,最後一個結點指標指向NULL。如圖:
一般地,我們為了方便,會在單連結串列的第一個結點前附設一個結點,稱為頭節點。頭節點的資料域可以不存任何資料,也可以存一些線性表的長度等資訊。
綜上,結點由存放資料元素的資料域和存放後繼結點的地址的指標域組成。
2、頭指標和頭節點的異同
頭指標:
- 頭指標是指連結串列指向第一個結點的指標,若連結串列由頭節點,則是指向第一個元素結點的指標;
- 頭指標具有標識作用,所以常用頭指標冠以連結串列的名字;
- 無論連結串列是否為空,頭指標均不為空。頭指標是連結串列的必要元素。
頭結點:
- 頭節點是為了操作的統一和方便而設立的,放在第一個元素結點之前,其資料域一般無意義;
- 有了頭節點,對在第一個元素結點前插入結點和刪除第一個元素結點,其操作與其他結點的操作就統一了;
- 頭節點不一定是連結串列的必要元素。
單連結串列的讀取
演算法思路:
- 宣告一個指標p指向連結串列第一個結點,初始化j從1開始;
- 當j<i時,就遍歷連結串列,讓p的指標向後移動,不斷指向下一個結點,j累加1;
- 若到連結串列末尾p為空,則說明第i個結點不存在;
- 否則查詢成功,返回結點p的資料。
其核心思想就是工作指標後移。其時間複雜度為O(n)。
單連結串列的插入和刪除
單連結串列的插入
看圖說話
演算法思路:
- 宣告一指標p指向連結串列頭節點,初始化j從1開始;
- 當j < i 時,就遍歷連結串列,讓p的指標向後移動,不斷指向下一個結點,j累加1;
- 若到連結串列末尾p為空,則說明第i個結點不存在;
- 否則查詢成功,在系統中生成一個空結點s;
- 將資料元素e賦值給 s->data;
- 單連結串列的插入標準語句 s->next; p->next=s;
- 返回成功。
單連結串列的刪除
上圖
演算法思路:
- 宣告一指標p指向連結串列的頭指標,初始化j從1開始;
- 當j< i時,就遍歷連結串列,讓p的指標向後移動,不斷指向下一個結點,j累加1;
- 若到連結串列末尾p為空,則說明第i個結點不存在;
- 否則查詢成功,將欲刪除的結點p->next賦值給q;
- 單連結串列的刪除標準語句 p->next=q->next;
- 將q結點中的資料賦值給e,作為返回;
- 釋放q結點;
- 返回成功。
從整個演算法來說,單連結串列的刪除和插入的時間複雜度都是O(n)。
顯然,對於插入或刪除資料越頻繁的操作,單連結串列的效率優勢就越明顯。
單連結串列的整表建立
順序儲存結構的建立,其實就是一個陣列的初始化,即宣告一個型別和大小的陣列並賦值的過程。
對於單連結串列來說,它所佔用的空間的大小和位置是不需要預先分配劃定的,可以根據系統情況即時生效。
演算法思路:
- 宣告一指標p和計數器變數i;
- 初始化一空連結串列L;
- 讓L的頭節點的指標指向NULL,即建立一個帶頭節點的單連結串列;
- 迴圈: 生成一新結點賦值給p; 隨機生成一個數字賦值給p的資料域p->data; 將p插入到頭節點與前一新結點之間。
以上思路稱作頭插法,當然對應還有尾插法,不再累贅。
單連結串列的整表刪除
演算法思路:
- 宣告一結點p和q;
- 將第一個結點賦值給p;
- 迴圈: 將下一節點賦值給q; 釋放p; 將q賦值給p。
兩種結構優缺點
儲存分配方式
- 順序儲存結構用一段來內需的儲存單元依次儲存線性表的資料元素;
- 單連結串列採用鏈式儲存結構,用一組任意的儲存單元存放線性表的元素;
時間效能
a、查詢 順序儲存結構O(1) 單連結串列O(n)
b、插入和刪除 順序儲存結構需要平均移動表長一般的元素,時間為O(n) 單連結串列在選出某位置的指標後,插入和刪除的時間僅為O(1)
空間效能
- 順序儲存結構需要預分配儲存空間,分大了,浪費,分小了易發生上溢;
- 單連結串列不需要分配儲存空間,只要有就可以分配,元素個數也不受限制。
總結來說:
- 順序結構查詢快,增刪慢;
- 連結串列 查詢慢,增刪快;
- 元素個數不大或根本不變或事先知道其最大容量時,可以採用順序儲存結構;
- 當元素變化大或根本不知道多大,應採用連結串列,不考慮記憶體空間大小的問題。
更多精彩內容,關注我的微信公眾號——Android機動車