資料結構 鍊錶

2021-10-07 19:21:26 字數 3869 閱讀 1233

做演算法題時最最重要的是清晰的思路,理清思路然後用**實現。

鍊錶可以分為單項鍊表、雙向鍊錶、以及環形鍊錶。它在記憶體中的儲存格式如下:

由圖可得:

鍊錶是以節點儲存資料,是鏈式儲存

每個節點包含data和next,data存放資料,next指向下乙個節點。

鍊錶的各個節點不一定是連續儲存

鍊錶可以分為帶頭節點的鍊錶和不帶頭節點的鍊錶。

一、單向鍊錶

單項鍊表最核心的思想是單向,可以理解為只能向乙個方向(從頭到尾)新增、遍歷、讀取資料。如圖:

二、雙向鍊錶

幾點說明:

單向鍊錶查詢的方向只能是乙個方向,而雙向鍊錶可以向前或向後雙向查詢。

單向鍊錶不能自我刪除(無法使刪除節點後的鍊錶連線起來),需要靠輔助節點。而雙向鍊錶,則可以自我刪除。所以刪除單鏈表的節點時,總是找到temp,temp是待刪除節點的前乙個節點。

注意:

呼叫在鍊錶中間新增、刪除節點的方法時,當遍歷到雙向鍊錶的最後乙個節點,要注意pre指標和next指標的指向問題,否則會出現空指標異常。

例:

刪除節點temp時,以下**

temp.pre.next = temp.next;

//構建向後的指標

temp.next.pre = temp.pre;

//構建向前的指標

作用最後乙個節點時,temp.next是乙個null,null.pre就會出現空指標異常。

三、環形鍊錶

這裡用乙個問題(約瑟夫環)引出環形鍊錶。

josephu問題:設編號為1,2,…n的n個人圍坐一圈,約定編號為k(1<=k<=n)的人從1開始報數,數到m的那個人出列,它的下一位又從1開始報數,數到m的那個人又出列,依次類推,直到所有人出列為止,由此產生乙個出隊編號的序列。

用單向環形鍊錶清楚直觀的解決josephu問題。

總思路:

先構成乙個有n個結點的單迴圈鍊錶,然後由k結點起從1開始計數,計到m時,對應結點從鍊錶中刪除,然後再從被刪除結點的下乙個結點又從1開始計數,直到最後乙個結點從鍊錶中刪除演算法結束。

構建單向環形鍊錶思路:

先建立第乙個節點, 讓 first 指向該節點,並形成環形(:first指標不能動,因為後面加入的節點要指向first,形成環形)

每當建立乙個新的節點(boy節點),就把該節點,加入到已有的環形鍊錶中即可。

curboy指標必須指向的是新加入的boy節點的前乙個節點,因為是單向鍊錶,只能單向新增節點(單向鍊錶的特性)。

遍歷環形鍊錶:

先讓乙個輔助指標(變數) curboy,指向first節點。

然後通過乙個while迴圈遍歷環形鍊錶即可,當curboy.next == first 結束。

出圈思路:

3. 先建立乙個輔助指標(變數) helper , 先指向環形鍊錶的最後這個節點.

補充: 小孩報數前,先讓 first 和 helper 移動 k - 1 次

4. 當小孩報數時,讓first 和 helper 指標同時 的移動 m - 1 次

5. 這時就可以將first 指向boy的節點出圈。

出圈步驟:

first = first .next (first指標後移)

helper.next = first

原來first 指向的節點就沒有任何引用,就會被**

talk is cheap. show me the code.

package datastructure.linkedlist;

public

class

joseph

}class

circlesinglelinkedlist

// 建立要給輔助指標,幫助完成小孩出圈

boy helper = first;

// 需求建立乙個輔助指標(變數) helper , 事先應該指向環形鍊錶的最後這個節點

while

(helper.

getnext()

!= first)

//小孩報數前,先讓 first 和 helper 移動 k - 1次

for(

int j =

0; j < startno -

1; j++

)//當小孩報數時,讓first 和 helper 指標同時 的移動 m - 1 次, 然後出圈

//這裡是乙個迴圈操作,知道圈中只有乙個節點

while

(helper != first)

//這時first指向的節點,就是要出圈的小孩節點

system.out.

printf

("小孩%d出圈\n"

, first.

getno()

);//這時將first指向的小孩節點出圈

first = first.

getnext()

; helper.

setnext

(first);}

system.out.

printf

("最後留在圈中的小孩編號%d\n"

, first.

getno()

);}public

void

addboy

(int num)

boy curboy = null;

// 輔助指標,幫助構建環形鍊錶

for(

int i =

1; i <= num; i++

)else}}

// 遍歷當前的環形鍊錶

public

void

showboy()

boy cur = first;

while

(true

) cur = cur.

getnext()

;//後移}}

}// 建立乙個boy類,表示乙個節點

class

boypublic

intgetno()

public

void

setno

(int no)

public boy getnext()

public

void

setnext

(boy next)

}

資料結構 鍊錶

鍊錶 what 就是一張鏈式儲存的表,是一種資料結構,是基礎,所以還是不要想有什麼用。具體呢?在c中就用結構體實現物件描述,然後通過函式來實現各個基本操作 c 則用類來表述,c中的結構體就可以看成c 中的類,然後通過類封裝各個操作步驟。這些操作實現後就需要 來測試,號稱demo,就是main函式裡面...

資料結構 鍊錶

鍊錶中的資料是以節點來表示的,每個結點的構成 元素 資料元素的映象 指標 指示後繼元素儲存位置 元素就是儲存資料的儲存單元,指標就是連線每個結點的位址資料。鍊錶的結點結構 data next data域 存放結點值的資料域 next域 存放結點的直接後繼的位址 位置 的指標域 鏈域 以 結點的序列 ...

資料結構 鍊錶

一般的建立線性鍊錶有兩種 1.正序法 需要三個指標,head作為頭指標,pre作為前乙個指標,cur作為當前指標用來建立空間 2.倒序法,利用指標的插入,只需要兩個指標,不斷的往頭指標後插入新空間,不過插入的越早,離頭指標越遠,也就越後面輸出 1.線性鍊錶的建立及查詢刪除 include inclu...