陣列在程式語言中用的非常有用,但是屬陣列至少有兩個缺點
(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...