3 1 單鏈表

2022-03-16 09:34:59 字數 3974 閱讀 6843

陣列在程式語言中用的非常有用,但是屬陣列至少有兩個缺點

(1) 編譯時就得知道陣列的大小

(2) 在計算機記憶體中是連續儲存的,這就意味著在陣列中插入或刪除乙個資料,就需要調整其他資料。

而使用鍊錶結構就不存在這些問題

下圖表示乙個鍊錶的結構及其構造過程。

上圖所示的鍊錶中

的每個節點都是下面

類定義(節點值為整數型)

的乙個例項:

這是一種c++物件導向的寫法,在c語言中,我們習慣定義成結構體。

class

intsllnode

intsllnode

(inti,

intsllnode

*in =0

)int

info

;intsllnode

*next

;//指向下乙個節點,這個節點的型別與本節點相同,這裡要定義成公有成員,以便實施鍊錶的操作

};

節點包含兩個數椐成員: info 和 next,  info 成員用於對使用者有用的儲存, next 是用於連線鍊錶節點對從而形成鍊錶結構。

有了這個定義我們就可以構造上圖所示的鍊錶了:

intsllnode *p = new intsllnode(10);

p->next = new intsllnode(8);

p->next->next = new intsllnode(50);

這裡僅定義了乙個頭指標p來訪問資料,不是很方便,在實際操作中一般會定義兩個指標或更多指標方便操作。

鍊錶節點型別已經由類intsllnode定義好了,接下來就是定義乙個類實施對鍊錶的各種錯作,單鏈表的操作無非是

增刪查改

定義下面的類intsllist

class

intsllist

~

intsllist

();int

isempty

()void

addtohead

(int

);void

addtotail

(int

);int

deletefromhead

();// delete the head and return its info;

int

deletefromtail

();// delete the tail and return its info;

void

deletenode

(int

);bool

isinlist

(int

)const

;void

printall

()const

;private

:intsllnode

*head,*

tail

;//兩個私有成員變數,分別是指向單鏈表的頭和尾的指標

};

2.1 插入

(1)新增到鍊錶開頭

四步:void

intsllist

::addtohead

(intel)

(2)新增到鍊錶末尾

四步:void

intsllist

::addtotail

(intel)

else

head

=tail

=new

intsllnode(el

);}

2.2 刪除

(1)刪除頭節點並返回它的值

為了程式的嚴謹需要考慮兩種特殊情況:

int

intsllist

::deletefromhead

()else

//std::cout<

return0;

}

注意:上面的程式實際上有乙個問題,程式開始用if語句檢查了鍊錶是否為空,假如為空就就會執行else的操作返回0;而對於呼叫

這個方法的語句並不知道返回的0是頭節點本身的值是0,還是因為鍊錶為空而返回的0。最好的解決方法是呼叫此方法之前就判定一

下鍊錶是否為空。

(2)刪除尾節點並返回它的值

該刪除操作由成員函式 deletefromtail實現。 問題在刪除了尾節點之後, tail應當指向鍊錶的新末尾節點,也就是說, tail 必須反方向移動乙個節點,但是因為從最後乙個節點到它的前驅節點沒有直接的鏈結,所以無法進行反方向移動。 因此必須從鍊錶的幵頭查詢這個前驅 節點,並恰好在tail前面停止。這個任務是通過在for在 迴圈中用個臨時變數temp遍歷鍊錶完成的 。

int

intsllist

::deletefromtail

()else

return

el;}

(3) 刪除值為el的節點

前面討論的這兩種刪除操作是從開頭或者末尾刪除乙個節點。如果要刪除乙個包含特定整數的節點,而不關心這個節點在鍊錶中的位置就需要使用不同的方法。這個節點也許正好在鍊錶的開頭、末尾,或者在鍊錶中的任何位置。簡單地說,必須先找到這個節點, 然後將其前驅節點與後繼節點連線,從而將其從鍊錶中刪除。因為不知道該節點在什麼位置, 操作複雜得多。

將前驅結點以及後繼節點連線起來就 能從鍊錶中刪除這個節點 ,但是因為鍊錶只有向後的鏈結,因此無法從某個節點獲得其前驅。完成這個懺務的方法之一是先掃瞄鍊錶找到處要

刪除的節點,然後再次掃瞄鍊錶找到它的前驅,另一種方法如下圖所示,借助兩個指標變數pred和tmp。

前面的圖只討論了 一種情況,還有下面幾種情況:

void

intsllist

::deletenode

(intel)

elseif(

el ==

head

->

info

)else

}

}

}

2.3 查詢

插入和刪除操作都對鍊錶進行了修改。查詢操作掃瞄已有的鍊錶,以確定其中是否包含某個數, 在此用布林成員函式 isinlist()實現這個操作。

bool

intsllist

::isinlist

(intel)

const

完整**:

來自為知筆記(wiz)

單鏈表(合併單鏈表)

單鏈表遍歷 單鏈表遍歷是從單鏈表頭指標head開始訪問,沿著next指標所指示的方向依次訪問每乙個結點,且每個結點只能訪問依次,直到最後乙個結點為止。遍歷時注意,不要改變head指標的指向。因此一般設定另外的乙個指標變數如p,p從head開始依次訪問乙個結點,直到鍊錶結束,此時p null,完成依次...

第4周專案3 1 單鏈表應用

問題及 檔名稱 cpp1.作 者 薛瑞琪 完成日期 2017 年 9 月 21 日 版 本 號 v1.0 問題描述 設計乙個演算法,將乙個帶頭結點的資料域依次為a1,a2,an n 3 的單鏈表的所有結點逆置,即第乙個結點的資料域變為an,最後乙個結點的資料域為a1。輸入描述 無需輸入 程式輸出 建...

單鏈表之排序單鏈表

package list public class sortedsinglylist extends singlylist 將values陣列中的所有物件按值大小插入 public sortedsinglylist t values 過載深拷貝,由單鏈表構建排序單鏈表 public sortedsi...