国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn))

這篇具有很好參考價(jià)值的文章主要介紹了【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn))。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

=========================================================================

相關(guān)代碼gitee自取

C語言學(xué)習(xí)日記: 加油努力 (gitee.com)

?=========================================================================

接上期

【數(shù)據(jù)結(jié)構(gòu)初階】二、 線性表里的順序表(C語言實(shí)現(xiàn)順序表)-CSDN博客

?=========================================================================

? ? ? ? ? ? ? ? ? ?

引言

通過上期對順序表介紹使用

我們可以知道順序表有以下優(yōu)點(diǎn)缺點(diǎn):

? ? ? ? ? ??

順序表優(yōu)點(diǎn)

? ? ? ? ? ? ? ? ??

  • 尾插尾刪 操作足夠快
    ? ? ? ? ? ? ? ?
  • 能夠使用下標(biāo)隨機(jī)訪問修改,這是很方便

? ? ? ? ? ??

-----------------------------------------------------------------------------------------------

? ? ? ? ? ??

順序表缺點(diǎn)

? ? ? ? ? ? ? ? ??

  • 頭部/中間插入刪除操作較慢,時(shí)間復(fù)雜度為O(N)
    ? ? ? ? ? ? ? ? ? ? ? ? ??
  • 增容需要申請新空間,拷貝數(shù)據(jù)釋放舊空間。會(huì)有不小的消耗
    ? ? ? ? ? ? ? ? ? ? ?
  • 增容一般呈2倍的增長,勢必會(huì)有一定的空間浪費(fèi)。
    例如:
    當(dāng)前容量100,滿了以后增容到 200,我們再繼續(xù)插入了5個(gè)數(shù)據(jù)
    后面沒有數(shù)據(jù)插入了,那么就浪費(fèi)了95個(gè)數(shù)據(jù)空間。

? ? ? ? ? ??

? ? ? ? ? ??

下面將要介紹和實(shí)現(xiàn)的鏈表不會(huì)出現(xiàn)這些問題

? ? ? ? ?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

? ? ? ? ? ? ?

1 . 鏈表

(1). 鏈表的概念及結(jié)構(gòu):

? ? ? ? ? ?

鏈表的概念

鏈表是一種物理存儲(chǔ)結(jié)構(gòu)非連續(xù)、非順序存儲(chǔ)結(jié)構(gòu),

數(shù)據(jù)元素的邏輯順序通過鏈表中的指針鏈接次序實(shí)現(xiàn)的,
單鏈表一般不會(huì)單獨(dú)使用,
只有頭插頭刪實(shí)現(xiàn)簡單效率高

? ? ? ? ? ? ??

鏈表的結(jié)構(gòu)

  • 鏈表屬于線性表,線性表物理存儲(chǔ)時(shí),
    通常數(shù)組(順序表)鏈?zhǔn)浇Y(jié)構(gòu)(鏈表)形式存儲(chǔ)
    鏈?zhǔn)浇Y(jié)構(gòu)邏輯上連續(xù)的,但在物理上不一定連續(xù)
    ? ? ? ? ? ? ? ? ?
  • 現(xiàn)實(shí)中的結(jié)點(diǎn)一般是從堆上申請出來的
    ? ? ? ? ? ? ??
  • 從堆上申請的空間,是按照一定的策略來分配的,
    兩次申請的空間可能連續(xù),也可能不連續(xù)
圖示:

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ? ? ? ? ? ?


? ? ? ? ? ? ? ? ? ??

(2). 鏈表的分類:

? ? ? ? ? ??

實(shí)際鏈表的結(jié)構(gòu)非常多樣,
以下情況組合起來就有8種鏈表結(jié)構(gòu)

? ? ? ? ? ?

單向 或 雙向 鏈表

單向鏈表圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ? ? ??

雙向鏈表圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------文章來源地址http://www.zghlxwxcb.cn/news/detail-715785.html

? ? ? ? ? ??

帶頭(哨兵位)?或 不帶頭(哨兵位) 鏈表

帶頭鏈表圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ? ? ?

不帶頭鏈表圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

循環(huán) 或 非循環(huán) 鏈表

循環(huán)鏈表圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ? ? ? ??

非循環(huán)鏈表圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

雖然有這么多的鏈表的結(jié)構(gòu),
但是我們實(shí)際中最常用還是兩種結(jié)構(gòu)

無頭單向非循環(huán)鏈表 和?帶頭雙向循環(huán)鏈表

? ? ? ? ? ? ? ? ? ? ?


? ? ? ? ? ? ? ? ? ??

(3). 兩種常用鏈表結(jié)構(gòu):

? ? ? ? ? ??

無頭單向非循環(huán)鏈表

簡介:

結(jié)構(gòu)簡單,一般不會(huì)單獨(dú)用來存數(shù)據(jù)

實(shí)際中更多是作為其他數(shù)據(jù)結(jié)構(gòu)的子結(jié)構(gòu),

哈希桶、圖的鄰接表等等

另外這種結(jié)構(gòu)在筆試面試中出現(xiàn)很多。

? ? ? ? ??

圖示:

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

帶頭雙向循環(huán)鏈表

簡介:

結(jié)構(gòu)最復(fù)雜,一般用在單獨(dú)存儲(chǔ)數(shù)據(jù)。

實(shí)際中使用的鏈表數(shù)據(jù)結(jié)構(gòu),都是帶頭雙向循環(huán)鏈表。

另外這個(gè)結(jié)構(gòu)雖然結(jié)構(gòu)復(fù)雜

但是使用代碼實(shí)現(xiàn)以后會(huì)發(fā)現(xiàn)結(jié)構(gòu)會(huì)帶來很多優(yōu)勢,實(shí)現(xiàn)反而簡單

? ? ? ? ??

圖示:

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

? ? ? ? ? ? ?

2 . 鏈表的實(shí)現(xiàn) (無頭+單向+非循環(huán)鏈表)

(詳細(xì)解釋在圖片的注釋中,代碼分文件放最后)

? ? ? ? ? ? ? ? ??

實(shí)現(xiàn)具體功能前的準(zhǔn)備工作

  • 創(chuàng)建單鏈表數(shù)據(jù)類型 -- 鏈表結(jié)點(diǎn)中數(shù)據(jù)域里存儲(chǔ)的數(shù)據(jù)的類型
    ? ? ? ? ? ? ? ??
  • 創(chuàng)建單鏈表結(jié)點(diǎn)結(jié)構(gòu)體(類型) -- 結(jié)點(diǎn)中應(yīng)有 數(shù)據(jù)域 指針域
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

PrintSList函數(shù) -- 遍歷打印鏈表

  • 需要使用鏈表頭指針phead,為了后續(xù)使用不能改變頭指針,所以要代替頭指針
    ? ? ? ? ? ? ? ? ?
  • 因?yàn)?span style="color:#fe2c24;">鏈表到最后結(jié)點(diǎn)里指針域的NULL(0x00000000)才結(jié)束,
    所以可以使用while循環(huán)進(jìn)行遍歷并打印
    ? ? ? ? ? ? ??
  • 最后提示已指向NULL指針鏈表遍歷結(jié)束
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTNode函數(shù) -- 生成鏈表的結(jié)點(diǎn)

  • 開辟結(jié)點(diǎn)所需的動(dòng)態(tài)空間,要注意一個(gè)結(jié)點(diǎn)大小看數(shù)據(jù)域和指針域的大小
    ? ? ? ? ? ?
  • 檢查空間是否開辟成功
    ? ? ? ? ? ?
  • 將要放入結(jié)點(diǎn)數(shù)據(jù)域的數(shù)據(jù)放入
    ? ? ? ? ? ?
  • 設(shè)置新創(chuàng)建結(jié)點(diǎn)的指針域
    ? ? ? ? ? ?
  • 返回創(chuàng)建的新結(jié)點(diǎn)的指針(地址)
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

測試 --?PrintSList、SLTNode函數(shù)

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTPushBack函數(shù)(難) -- 向鏈表尾部插入一個(gè)結(jié)點(diǎn)(尾插)

  • 因?yàn)?span style="color:#fe2c24;">要插入一個(gè)結(jié)點(diǎn),所以先使用BuySListNode函數(shù)創(chuàng)建一個(gè)結(jié)點(diǎn)
    ? ? ? ? ? ?
  • 尾插時(shí)要判斷鏈表是否已經(jīng)有結(jié)點(diǎn),
    如果沒有結(jié)點(diǎn),
    將新創(chuàng)建結(jié)點(diǎn)的地址賦給頭指針
    因?yàn)槭?span style="color:#fe2c24;">對指針本身進(jìn)行操作,所以二級指針對頭指針進(jìn)行操作
    ? ? ? ? ? ?
  • 如果已經(jīng)有了結(jié)點(diǎn),
    先創(chuàng)建一個(gè)指針替代頭指針
    (這里是對頭指針直線的結(jié)點(diǎn)結(jié)構(gòu)體進(jìn)行操作,所以用指針就夠了不需要二級指針
    使用while循環(huán)獲得最后一個(gè)結(jié)點(diǎn)的地址,
    最后將尾插的結(jié)點(diǎn)連接起來
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

(可以結(jié)合單鏈表物理圖來理解

↓↓↓↓

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

測試 --?SLTPushBack函數(shù)

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTPushFront函數(shù) --?向鏈表頭部插入一個(gè)結(jié)點(diǎn)(頭插)

  • 因?yàn)?span style="color:#fe2c24;">要插入一個(gè)結(jié)點(diǎn),所以先使用BuySListNode函數(shù)創(chuàng)建一個(gè)結(jié)點(diǎn)
    ? ? ? ? ? ?
  • 使用plist把原本頭結(jié)點(diǎn)地址賦給新插入頭結(jié)點(diǎn)指針域
    ? ? ? ? ? ?
  • 再把頭指針改為指向新插入頭結(jié)點(diǎn)
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

測試 -- SLTPushFront函數(shù)

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTPopBack函數(shù) --?刪除鏈表尾部結(jié)點(diǎn)(尾刪)

  • 鏈表尾刪考慮三種情況
    第一種情況鏈表為空,沒有任何結(jié)點(diǎn)
    這種情況直接assert斷言即可
    ? ? ? ? ? ?
  • 第二種情況鏈表只有一個(gè)結(jié)點(diǎn)
    這種情況要釋放掉唯一的結(jié)點(diǎn)
    ? ? ? ? ? ?
  • 第三種情況鏈表有一個(gè)以上結(jié)點(diǎn)
    這種情況需要兩個(gè)指針來進(jìn)行操作
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

測試 -- SLTPopBack函數(shù)

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTPopFront函數(shù) --?刪除鏈表頭部結(jié)點(diǎn)(頭刪)

  • 頭刪分兩種情況就夠了:空鏈表 非空鏈表
    ? ? ? ? ? ?
  • 空鏈表頭刪
    直接assert斷言pass掉
    (莫名戳中笑點(diǎn)哈哈哈哈哈哈哈哈)
    ? ? ? ? ? ?
  • 非空鏈表頭刪
    通過plist頭指針獲得第二個(gè)結(jié)點(diǎn)地址,方便頭刪后讓原本的第二個(gè)結(jié)點(diǎn)做新的頭結(jié)點(diǎn)
    free釋放掉頭指針,
    最后讓plist頭指針指向原本的第二個(gè)結(jié)點(diǎn)做新的頭結(jié)點(diǎn)
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

測試 -- SLTPopFront函數(shù)

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTFind函數(shù) --?查找指定值(x)所在結(jié)點(diǎn)的地址

  • 創(chuàng)建一個(gè)變量代替頭指針
    ? ? ? ? ? ?
  • 使用while循環(huán)在鏈表中進(jìn)行遍歷,查找指定值(x)
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

測試 -- SLTFind函數(shù)

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTInsert函數(shù) --?在鏈表指定位置(pos)之前插入一個(gè)值(x)

  • 分三種情況討論
    鏈表為空(空鏈表)、在第一個(gè)結(jié)點(diǎn)前插入(頭插)、非頭插
    ? ? ? ? ? ?
  • 鏈表為空
    直接assert斷言pass掉
    ? ? ? ? ? ?
  • 在第一個(gè)結(jié)點(diǎn)前插入(頭插)
    復(fù)用頭插SLTPushFront函數(shù)進(jìn)行插入
    ? ? ? ? ? ?
  • 非頭插
    使用鏈表頭指針找到pos結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)地址prev
  • 創(chuàng)建一個(gè)新結(jié)點(diǎn)newnode
    將新結(jié)點(diǎn)newnode插入pos結(jié)點(diǎn)之前,prev結(jié)點(diǎn)之后
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

測試 -- SLTInsert函數(shù)

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTInsertAfter函數(shù) --?在鏈表指定位置(pos)之后插入一個(gè)值(x)

  • 如果接收的pos結(jié)點(diǎn)地址為空,無法繼續(xù)操作
    用assert斷言繼續(xù)處理
    ? ? ? ? ? ?
  • 因?yàn)橐?span style="color:#fe2c24;">在鏈表中插入一個(gè)值,
    所以要用BuySListNode函數(shù)新增一個(gè)結(jié)點(diǎn)
    ? ? ? ? ? ?
  • 讓newnode結(jié)點(diǎn)的指針域next指向后一個(gè)結(jié)點(diǎn)
    ? ? ? ? ? ?
  • 讓pos結(jié)點(diǎn)指向newnode結(jié)點(diǎn)
    將鏈表連接起來
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

測試 -- SLTInsertAfter函數(shù)

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTErase函數(shù) --?在鏈表刪除指定位置(pos)結(jié)點(diǎn)

  • 防止要?jiǎng)h的pos結(jié)點(diǎn)指針為空指針,
    使用assert斷言
    ? ? ? ? ? ?
  • 分兩種情況
    頭刪非頭刪
    ? ? ? ? ? ?
  • 頭刪
    直接復(fù)用頭刪SLTPopFront函數(shù)
    ? ? ? ? ? ?
  • 非頭刪
    找到pos結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)prev,
    prev結(jié)點(diǎn) pos結(jié)點(diǎn)后一個(gè)結(jié)點(diǎn) 連接起來
    ? ? ? ? ? ?
  • 最后釋放(刪除)pos結(jié)點(diǎn)完成刪除操作
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

測試 -- SLTErase函數(shù)

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTEraseAfter函數(shù) --?在鏈表刪除指定位置(pos)之后一個(gè)結(jié)點(diǎn)

  • 使用assert斷言分別排除pos結(jié)點(diǎn)指針為空pos結(jié)點(diǎn)為尾結(jié)點(diǎn)的情況,
    我們是刪除pos結(jié)點(diǎn)的后一個(gè)結(jié)點(diǎn),
    如果pos為尾結(jié)點(diǎn),就會(huì)無法操作
    ? ? ? ? ? ?
  • 將要?jiǎng)h除的pos結(jié)點(diǎn)下個(gè)結(jié)點(diǎn)posNext地址保存起來
    ? ? ? ? ? ?
  • pos結(jié)點(diǎn)下下個(gè)結(jié)點(diǎn)連接起來
    ? ? ? ? ? ?
  • 最后釋放(刪除)posNext結(jié)點(diǎn)
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

測試 -- SLTEraseAfter函數(shù)

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

? ? ? ? ? ??

SLTDestroy函數(shù) --?銷毀鏈表釋放開辟的動(dòng)態(tài)空間

  • 因?yàn)?span style="color:#fe2c24;">鏈表釋放后,還要把頭指針plist給置為空,
    要操作到plist,所以要用到二級指針
    ? ? ? ? ? ?
  • 進(jìn)行assert斷言,
    pphead二級指針不為空
    以上函數(shù)中參數(shù)帶二級指針pphead的都需要進(jìn)行此操作
    ? ? ? ? ? ?
  • 創(chuàng)建一個(gè)指針進(jìn)行遍歷釋放空間
    ? ? ? ? ? ?
  • 最后將鏈表頭指針置為空
圖示

【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn)),CCC全是C,數(shù)據(jù)結(jié)構(gòu),鏈表,c語言

? ? ? ? ?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

? ? ? ? ? ? ?

3 . 對應(yīng)代碼

SList.h?-- 單鏈表頭文件

//鏈表頭文件:
#pragma once

//先包含之后要用到的頭文件:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


//重命名一個(gè)單鏈表數(shù)據(jù)類型
typedef int SLTDataType;
//SLT -- single link table

//創(chuàng)建一個(gè)單鏈表結(jié)點(diǎn)結(jié)構(gòu)體 
//這里數(shù)據(jù)域是int類型4字節(jié),指針域指針也是4個(gè)字節(jié),
//所以一個(gè)結(jié)點(diǎn)就是8個(gè)字節(jié)
typedef struct SListNode
{
	//結(jié)點(diǎn)數(shù)據(jù)域:
	SLTDataType data;

	//結(jié)點(diǎn)指針域:
	//因?yàn)槭侵赶騿捂湵斫Y(jié)點(diǎn)結(jié)構(gòu)體的指針,
	//所以是單鏈表結(jié)點(diǎn)結(jié)構(gòu)體類型的指針
	struct SListNode* next;
	//第一個(gè)結(jié)點(diǎn)要找到第二個(gè)結(jié)點(diǎn),物理空間不連續(xù)
	//通過上個(gè)結(jié)點(diǎn)指向下個(gè)結(jié)點(diǎn),實(shí)現(xiàn)邏輯連續(xù)

}SLTNode; //將struct SListNode重命名為SLTNode


//創(chuàng)建遍歷打印單鏈表的函數(shù) -- 接收單鏈表頭指針
void PrintSList(SLTNode* phead);

   
//創(chuàng)建生成結(jié)點(diǎn)的函數(shù) -- 接收要存入結(jié)點(diǎn)數(shù)據(jù)域的數(shù)據(jù);返回該結(jié)點(diǎn)的指針
SLTNode* BuySListNode(SLTDataType x);


//創(chuàng)建尾插函數(shù) -- 
//使用二級指針接收單鏈表頭指針的地址 和 接收要插入的值
void SLTPushBack(SLTNode** pphead, SLTDataType x);


//創(chuàng)建頭插函數(shù) -- 
//使用二級指針接收單鏈表頭指針的地址 和 接收要插入的值
void SLTPushFront(SLTNode** pphead, SLTDataType x);



//創(chuàng)建尾刪函數(shù) --
//使用二級指針接收單鏈表頭指針的地址
void SLTPopBack(SLTNode** pphead);


//創(chuàng)建頭刪函數(shù) --
//使用二級指針接收單鏈表頭指針的地址
void SLTPopFront(SLTNode** pphead);


//創(chuàng)建查找函數(shù) --
//查找指定值(x)所在結(jié)點(diǎn)的地址
//接收 鏈表頭指針phead、查找值x
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);


//創(chuàng)建指定位置插入函數(shù)1 --
//在鏈表指定位置(pos)之前插入一個(gè)值(x)
//接收 鏈表頭指針地址pphead、指定結(jié)點(diǎn)指針pos、插入值x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);


//創(chuàng)建指定位置插入函數(shù)2 --
//在鏈表指定位置(pos)之后插入一個(gè)值(x)
//接收 指定結(jié)點(diǎn)指針pos、插入值x
void SLTInsertAfter(SLTNode* pos, SLTDataType x);


//創(chuàng)建刪除指定結(jié)點(diǎn)函數(shù)1 --
//在鏈表刪除指定位置(pos)結(jié)點(diǎn)
///接收 鏈表頭指針地址pphead、指定結(jié)點(diǎn)指針pos
void SLTErase(SLTNode** pphead, SLTNode* pos);


//創(chuàng)建刪除指定結(jié)點(diǎn)函數(shù)2 --
//在鏈表刪除指定位置(pos)之后一個(gè)結(jié)點(diǎn)
//接收 指定結(jié)點(diǎn)指針pos
void SLTEraseAfter(SLTNode* pos);


//創(chuàng)建銷毀鏈表函數(shù):
void SLTDestroy(SLTNode** pphead);

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

SList.c?-- 單鏈表函數(shù)實(shí)現(xiàn)文件

//鏈表實(shí)現(xiàn)文件:
#define _CRT_SECURE_NO_WARNINGS 1

//包含鏈表頭文件:
#include "SList.h"

//創(chuàng)建遍歷單鏈表的函數(shù):接收單鏈表結(jié)點(diǎn)的頭指針
void PrintSList(SLTNode* phead)
{
	//phead頭指針指向第一個(gè)結(jié)點(diǎn),
	//之后還要多次使用phead頭指針,
	//所以不要改變phead頭指針,
	//所以可以創(chuàng)建一個(gè)和phead頭指針一樣類型的指針cur代替phead頭指針
	SLTNode* cur = phead;

	//因?yàn)殒湵淼阶詈蠼Y(jié)點(diǎn)的指針域?yàn)镹ULL才結(jié)束
	//所以只要cur不為NULL就繼續(xù)遍歷結(jié)點(diǎn)進(jìn)行打?。?	while (cur != NULL)
	{
		//通過cur當(dāng)前指向的結(jié)點(diǎn)打印cur里數(shù)據(jù)域的內(nèi)容:
		printf("%d->", cur->data);

		//通過結(jié)點(diǎn)里指針域指向下一個(gè)結(jié)點(diǎn),方便打印下個(gè)結(jié)點(diǎn)的數(shù)據(jù)域內(nèi)容
		cur = cur->next;
	}

	//最后提示已指向NULL指針鏈表,遍歷結(jié)束:
	printf("NULL\n");
}



//創(chuàng)建生成結(jié)點(diǎn)的函數(shù) -- 接收要存入結(jié)點(diǎn)數(shù)據(jù)域的數(shù)據(jù);返回該結(jié)點(diǎn)的指針
SLTNode* BuySListNode(SLTDataType x)
{
	//給結(jié)點(diǎn)開辟動(dòng)態(tài)空間(注意開辟空間的大小是SLTNode結(jié)點(diǎn)的大小--8個(gè)字節(jié))
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode)); 
	//返回該結(jié)點(diǎn)地址

	//檢查是否開辟成功:
	if (newnode == NULL) //返回空指針,說明開辟失敗
	{
		//打印錯(cuò)誤信息:
		perror("malloc fail");
		//開辟失敗直接退出程序:
		exit(-1);
	}

	//將接收的值x賦給該結(jié)點(diǎn)的數(shù)據(jù)域:
	newnode->data = x;

	//設(shè)置新創(chuàng)建結(jié)點(diǎn)的指針域:
	//因?yàn)槭亲钚碌慕Y(jié)點(diǎn),即最尾部的結(jié)點(diǎn),
	//所以指針域的指針應(yīng)是NULL(鏈表末尾結(jié)束)
	//之后通過指針域連接各個(gè)結(jié)點(diǎn)的操作要看情況操作,先都初始化為NULL
	newnode->next = NULL;

	//返回該新結(jié)點(diǎn)的指針(地址)
	return newnode;
}



//創(chuàng)建尾插函數(shù)
//使用二級指針接收單鏈表頭指針的地址 和 接收要插入的值
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	//改變結(jié)構(gòu)體,要用結(jié)構(gòu)體指針
	//改變結(jié)構(gòu)體指針,要用結(jié)構(gòu)體指針的指針(二級指針)
	   
	//因?yàn)閜phead二級指針存儲(chǔ)的是plist指針,
	//plist指針指向的值可能為空,但指針的地址不能為空
	//pphead是plist的地址,正常情況下一定不為空
	assert(pphead);

	//先使用newnode函數(shù)為要尾插的值創(chuàng)建一個(gè)結(jié)點(diǎn)
	//并返回該結(jié)點(diǎn)地址
	SLTNode* newnode = BuySListNode(x);

	//判斷phead是否是NULL,如果是說明鏈表還沒開辟過一個(gè)結(jié)點(diǎn)
	if (*pphead == NULL)
	{
		//如果為空,則將上面開辟的newnode結(jié)點(diǎn)地址賦給phead
		*pphead = newnode;
		//要改變結(jié)構(gòu)體的指針,就要用二級指針

		//這里pphead是二級指針,存放鏈表頭指針plist的地址
		//因?yàn)槿绻靡患壷羔楽LTNode* phead的話,
		//phead形參只是plist實(shí)參的臨時(shí)拷貝,兩者空間相互獨(dú)立
		//改變phead的話不會(huì)改變plist,plist還會(huì)是空指針
		//所以要用二級指針pphead存放plist指針的地址,
		//*pphead解引用就能得到一級指針plist,
		//即			*pphead = plist
		//所以實(shí)際上上面的代碼就相當(dāng)于:plist = newnode
		//這樣就讓本來指向空指針的頭指針指向了新創(chuàng)建的結(jié)點(diǎn)指針
		//鏈表就能夠連接起來
	}
	else
		//不為空則往尾部插入新結(jié)點(diǎn):
	{
		//創(chuàng)建另一個(gè)指針存放單鏈表頭指針
		SLTNode* tail = *pphead; //*pphead == plist

		//使用while循環(huán)獲得最后一個(gè)結(jié)點(diǎn)的地址
		while (tail->next != NULL)
		//如果下個(gè)結(jié)點(diǎn)的next指針域不為NULL,
		//則繼續(xù)往后找,直到tail等于最后結(jié)點(diǎn)的地址
		{
			//把當(dāng)前結(jié)點(diǎn)指針域里下個(gè)結(jié)點(diǎn)的地址給到tail,
			//進(jìn)行while循環(huán)下次判斷:
			tail = tail->next;
		}

		//tail找到最后結(jié)點(diǎn)地址后,
		//把尾插的新結(jié)點(diǎn)地址給到tail的next指針域,
		//連接起鏈表:
		tail->next = newnode;
		//要改變結(jié)構(gòu)體,用結(jié)構(gòu)體的指針即可

		//因?yàn)閚ewnode、tail、pphead都是臨時(shí)(局部)變量,
		//所以函數(shù)運(yùn)行結(jié)束后都會(huì)銷毀,
		//但malloc函數(shù)開辟的空間(結(jié)點(diǎn))都在堆上不會(huì)銷毀
		//通過解引用二級指針pphead改變plist也沒有問題
	}
}



//創(chuàng)建頭插函數(shù) -- 
//使用二級指針接收單鏈表頭指針的地址 和 接收要插入的值
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	//因?yàn)閜phead二級指針存儲(chǔ)的是plist指針,
	//plist指針指向的值可能為空,但指針的地址不能為空
	//pphead是plist的地址,正常情況下一定不為空
	assert(pphead);

	//先使用newnode函數(shù)為要頭插的值創(chuàng)建一個(gè)結(jié)點(diǎn)
	//并返回該結(jié)點(diǎn)地址
	SLTNode* newnode = BuySListNode(x);

	//因?yàn)橐惨玫芥湵眍^指針本身,所以也要使用二級指針
	//因?yàn)閜list指向原本頭結(jié)點(diǎn)地址,
	//所以可以使用plist把原本頭結(jié)點(diǎn)地址賦給新插入頭結(jié)點(diǎn)指針域:
	newnode->next = *pphead;

	//再把頭指針改為指向新插入頭結(jié)點(diǎn):
	*pphead = newnode;
}



//創(chuàng)建尾刪函數(shù) --
//使用二級指針接收單鏈表頭指針的地址
void SLTPopBack(SLTNode** pphead)
{
	//尾刪需要考慮三種情況:
	//注:*pphead 就是 plist
	
	//因?yàn)閜phead二級指針存儲(chǔ)的是plist指針,
	//plist指針指向的值可能為空,但指針的地址不能為空
	//pphead是plist的地址,正常情況下一定不為空
	assert(pphead);

	// 第一種情況:鏈表為空 -- 沒有任何結(jié)點(diǎn)
	//沒有結(jié)點(diǎn)那就刪不了了,使用assert接收到空指針就報(bào)警告
	assert(*pphead);

	// 第二種情況:鏈表只有一個(gè)結(jié)點(diǎn)
	if ((*pphead)->next == NULL)
		// -> 也是解引用(結(jié)構(gòu)體的),優(yōu)先級比 * 高
		//所以 *pphead 要用() 括起來
	{
		//只有一個(gè)結(jié)點(diǎn),又要尾刪,那就直接把這唯一的結(jié)點(diǎn)刪掉:
		free(*pphead); //直接free釋放掉plist指向的結(jié)點(diǎn)

		//再把釋放掉的plist置為空指針,防止成為野指針:
		*pphead = NULL;
	}
	else
	// 第三種情況:鏈表有一個(gè)以上結(jié)點(diǎn)
	{
		//這種情況額外兩個(gè)指針,
		//一個(gè)tail指針 -- 用來找到最后一個(gè)結(jié)點(diǎn)地址并將其釋放,
		//還有一個(gè)tailPrev指針 -- 指向tail指針的前一個(gè)結(jié)點(diǎn)地址,
		//用來改變該結(jié)點(diǎn)的指針域,
		//防止原本指向tail結(jié)點(diǎn)的指針域變成野指針

		//先替代頭指針plist:
		SLTNode* tail = *pphead;

		//創(chuàng)建tailPrev指針,
		//之后操作會(huì)指向tail結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn),
		//即倒數(shù)第二個(gè)結(jié)點(diǎn)
		SLTNode* tailPrev = NULL;

		//再使用while循環(huán)找到尾結(jié)點(diǎn):
		//和尾插的操作類似
		while (tail->next != NULL)
		{
			//tail查找之前先把當(dāng)前指向結(jié)點(diǎn)地址給tailPrev
			//這樣最后tail會(huì)指向尾結(jié)點(diǎn),
			//tailPrev會(huì)指向倒數(shù)第二個(gè)結(jié)點(diǎn)
			tailPrev = tail;

			tail = tail->next;
		}

		//結(jié)束while循環(huán)后tail指向尾結(jié)點(diǎn)地址,
		//因?yàn)槭俏矂h,所以free釋放掉tail就可以“刪掉”尾結(jié)點(diǎn)
		free(tail);
		//因?yàn)閠ail是局部(臨時(shí))變量,出了函數(shù)就銷毀,
		//所以不置為指針也可以,不用擔(dān)心成為野指針

		//刪除原尾結(jié)點(diǎn)后,倒數(shù)第二個(gè)結(jié)點(diǎn)成為尾結(jié)點(diǎn),
		//要把其指針域next置為空指針,成為鏈表新結(jié)尾
		tailPrev->next = NULL;
	}
}



//創(chuàng)建頭刪函數(shù) --
//使用二級指針接收單鏈表頭指針的地址
void SLTPopFront(SLTNode** pphead)
{
	//因?yàn)閜phead二級指針存儲(chǔ)的是plist指針,
	//plist指針指向的值可能為空,但指針的地址不能為空
	//pphead是plist的地址,正常情況下一定不為空
	assert(pphead);

	//分兩種情況:
	
	//第一種情況:鏈表里沒有結(jié)點(diǎn)(空鏈表)
	//沒有結(jié)點(diǎn)可以刪,直接assert斷言pass掉:
	assert(*pphead);


	//第二種情況:鏈表有一個(gè)和多個(gè)結(jié)點(diǎn)(非空鏈表)
	//因?yàn)槭莿h掉頭結(jié)點(diǎn),所以不用考慮找尾結(jié)點(diǎn)
	//所以不用細(xì)分一個(gè)或多個(gè)結(jié)點(diǎn)的情況:
	
	//這種情況要先通過plist拿到第二個(gè)結(jié)點(diǎn)的地址:
	SLTNode* newhead = (*pphead)->next;
	//使用newhead存儲(chǔ)第二個(gè)結(jié)點(diǎn)地址

	//拿到第二個(gè)結(jié)點(diǎn)地址后,再釋放掉頭結(jié)點(diǎn),
	//實(shí)現(xiàn)頭刪效果:
	free(*pphead);

	//這時(shí)要讓第二個(gè)結(jié)點(diǎn)成為新的頭結(jié)點(diǎn):
	*pphead = newhead; 
	//頭指針指向原本的第二個(gè)結(jié)點(diǎn)
}



//創(chuàng)建查找函數(shù) --
//查找指定值(x)所在結(jié)點(diǎn)的地址
//接收 鏈表頭指針phead、查找值x
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{
	//像SLTFind和PrintSList函數(shù)只用頭指針遍歷
	//不改變指針本身就不需要用到二級指針

	//創(chuàng)建個(gè)變量代替頭指針:
	SLTNode* cur = phead;

	//使用while循環(huán)對鏈表進(jìn)行遍歷查找:
	while (cur != NULL)
		//只要cur指針指向地址不為空就繼續(xù)循環(huán)
//while遍歷時(shí),(cur->next != NULL) 和 (cur != NULL) 的區(qū)別:
//(cur->next != NULL):這個(gè)條件最后cur會(huì)是最后結(jié)點(diǎn)的地址
//(cur != NULL):這個(gè)條件最后cur會(huì)是NULL
//(cur->next != NULL) 會(huì)比 (cur != NULL) 少一次循環(huán)
	{
		//遍歷過程中依次查找各結(jié)點(diǎn)數(shù)據(jù)域數(shù)據(jù)是否與x相同:
		if (cur->data == x)
		{
			//找到了一個(gè)結(jié)點(diǎn)數(shù)據(jù)域數(shù)據(jù)是x,返回該結(jié)點(diǎn)地址
			return cur;
		}
		//這里如果while循環(huán)的條件是(cur->next != NULL)
		//最后一個(gè)結(jié)點(diǎn)進(jìn)不來,不能判斷最后結(jié)點(diǎn)數(shù)據(jù)域數(shù)據(jù)是不是x

		cur = cur->next; //改變循環(huán)條件,指向下個(gè)結(jié)點(diǎn)
	}

	//如果能指向到這說明沒找到,返回NULL:
	return  NULL;
}



//創(chuàng)建指定位置插入函數(shù)1 -- 
//在鏈表指定位置(pos)之前插入一個(gè)值(x)
//接收 鏈表頭指針地址pphead、指定結(jié)點(diǎn)指針pos、插入值x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	//因?yàn)閜phead二級指針存儲(chǔ)的是plist指針,
	//plist指針指向的值可能為空,但指針的地址不能為空
	//pphead是plist的地址,正常情況下一定不為空
	assert(pphead);

	//第一種情況:空指針
	//先排除空指針的情況:
	assert(pos);

	//第二種情況:頭插
	if (pos == *pphead)
		// *pphead == plist
		//如果pos是pphead即第一個(gè)指針,
		//則在第一個(gè)指針前插入一個(gè)值,相當(dāng)于頭插
	{
		//直接復(fù)用頭插函數(shù)SLTPustFront:
		SLTPushFront(pphead, x);
		//直接傳pphead二級指針過去
	}
	else
	//第三種情況:非頭插
	{
		//從頭開始找pos結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn):
		//先獲得頭指針
		SLTNode* prev = *pphead;

		//當(dāng)前結(jié)點(diǎn)的指針域不是指向pos結(jié)點(diǎn)則繼續(xù)循環(huán)
		while (prev->next != pos)
		{
			prev = prev->next;
		}

		//此時(shí)prev已指向pos結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)

		//為要插入的結(jié)點(diǎn)創(chuàng)建一個(gè)結(jié)點(diǎn)newnode:
		//插入位置是pos結(jié)點(diǎn)之前,prev結(jié)點(diǎn)之后
		SLTNode* newnode = BuySListNode(x);

		//讓prev結(jié)點(diǎn)指針域指向新插入結(jié)點(diǎn)地址:
		prev->next = newnode;

		//newnode結(jié)點(diǎn)指針域指向pos結(jié)點(diǎn):
		newnode->next = pos;

		//此時(shí)newnode新結(jié)點(diǎn)就插入完成了
	}
}



//創(chuàng)建指定位置插入函數(shù)2 --
//在鏈表指定位置(pos)之后插入一個(gè)值(x)
//接收 指定結(jié)點(diǎn)指針pos、插入值x
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	//因?yàn)槭窃趐os結(jié)點(diǎn)后插入一個(gè)值(結(jié)點(diǎn))
	//所以不可能會(huì)有頭插的情況,那就不需要頭指針plist

	//pos指針存儲(chǔ)結(jié)點(diǎn)地址,可能會(huì)接收到空指針
	//使用assert斷言pass掉
	assert(pos);

	//先為插入值創(chuàng)建一個(gè)新結(jié)點(diǎn)newnode:
	SLTNode* newnode = BuySListNode(x);

	//先讓newnode的指針域next指向后一個(gè)結(jié)點(diǎn):
	//這里后一個(gè)結(jié)點(diǎn)就是pos結(jié)點(diǎn)指針域里的地址
	//因?yàn)槲床迦肭皃os就是指向后一個(gè)地址
	newnode->next = pos->next;

	//再讓pos的指針域next指向newnode:
	pos->next = newnode;
}



//創(chuàng)建刪除指定結(jié)點(diǎn)函數(shù)1 --
//在鏈表刪除指定位置(pos)結(jié)點(diǎn)
///接收 鏈表頭指針地址pphead、指定結(jié)點(diǎn)指針pos
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	//因?yàn)閜phead二級指針存儲(chǔ)的是plist指針,
	//plist指針指向的值可能為空,但指針的地址不能為空
	//pphead是plist的地址,正常情況下一定不為空
	assert(pphead);

	//防止要?jiǎng)h的pos結(jié)點(diǎn)指針為空指針
	//使用assert斷言:
	assert(pos);

	//分兩種情況:

	// 1.頭刪:
	if (pos == *pphead)
		//pos結(jié)點(diǎn) == 頭結(jié)點(diǎn) --> 頭刪
	{
		//直接復(fù)用SLTPopFront頭刪函數(shù):
		SLTPopFront(pphead);
	}
	else
	// 2.非頭刪:
	//尾刪不用單獨(dú)分出一種情況,因?yàn)檫€得判斷是不是尾結(jié)點(diǎn)
	//直接用通用邏輯刪除也可以處理尾刪的情況
	{
		//從頭開始找pos結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn):
		//先獲得頭指針
		SLTNode* prev = *pphead;

		//當(dāng)前結(jié)點(diǎn)的指針域不是指向pos結(jié)點(diǎn)則繼續(xù)循環(huán)
		while (prev->next != pos)
		{
			prev = prev->next;
		}

		//此時(shí)prev已指向pos結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)

		//因?yàn)橐獎(jiǎng)h除pos結(jié)點(diǎn),
		//所以要讓pos前一個(gè)和后一個(gè)結(jié)點(diǎn)連接起來:
		prev->next = pos->next;

		//連接成功后再把pos結(jié)點(diǎn)釋放,實(shí)現(xiàn)刪除效果:
		free(pos);
	}
}



//創(chuàng)建刪除指定結(jié)點(diǎn)函數(shù)2 --
//在鏈表刪除指定位置(pos)之后一個(gè)結(jié)點(diǎn)
//接收 指定結(jié)點(diǎn)指針pos
void SLTEraseAfter(SLTNode* pos)
{
	//刪除pos結(jié)點(diǎn)后的一個(gè)結(jié)點(diǎn),
	//那么就不可能出現(xiàn)頭刪的情況,
	//pos結(jié)點(diǎn)是尾結(jié)點(diǎn)也沒用,
	//因?yàn)槲步Y(jié)點(diǎn)后就沒有結(jié)點(diǎn)可以刪了
	//使用assert斷言處理:
	assert(pos); //防止接收“空結(jié)點(diǎn)”
	assert(pos->next); //防止接收尾結(jié)點(diǎn)

	//將要?jiǎng)h的pos結(jié)點(diǎn)的下個(gè)結(jié)點(diǎn)posNext先保存起來:
	SLTNode* posNext = pos->next;

	//再把pos結(jié)點(diǎn)和下下個(gè)結(jié)點(diǎn)連接起來:
	pos->next = posNext->next;
	//posNext的指針域next就是pos結(jié)點(diǎn)的下下個(gè)結(jié)點(diǎn)地址

	//最后釋放(刪除)posNext結(jié)點(diǎn):
	free(posNext);
}



//創(chuàng)建銷毀鏈表函數(shù):
void SLTDestroy(SLTNode** pphead)
{
	//因?yàn)殒湵磲尫藕?,還要把頭指針plist給置為空,
	//要操作到plist,所以要用到二級指針:

	//plist指向空鏈表,pphead也不能為空:
	assert(pphead);

	//創(chuàng)建一個(gè)指針進(jìn)行遍歷:
	SLTNode* cur = *pphead;//*pphead == plist
	//進(jìn)行遍歷釋放:
	while (cur != NULL)
	{
		//創(chuàng)建一個(gè)指針保存下個(gè)結(jié)點(diǎn)地址:
		SLTNode* next = cur->next;
		//釋放當(dāng)前結(jié)點(diǎn):
		free(cur);
		//cur指針移向下一個(gè)結(jié)點(diǎn):
		cur = next;
	}

	//將鏈表頭指針置為空:
	*pphead = NULL;
}

? ? ? ? ? ??

? ? ? ? ? ??

---------------------------------------------------------------------------------------------

test.c?-- 單鏈表測試文件

//鏈表測試文件:
#define _CRT_SECURE_NO_WARNINGS 1

/* 鏈表學(xué)習(xí)引入小測試:

#include <stdio.h>

//重命名一個(gè)單鏈表數(shù)據(jù)類型
typedef int SLTDataType;
//SLT -- single link table

//創(chuàng)建一個(gè)單鏈表結(jié)點(diǎn)結(jié)構(gòu)體
typedef struct SListNode
{
	//結(jié)點(diǎn)數(shù)據(jù)域:
	SLTDataType data; 

	//結(jié)點(diǎn)指針域:
	//因?yàn)槭侵赶騿捂湵斫Y(jié)點(diǎn)結(jié)構(gòu)體的指針,
	//所以是單鏈表結(jié)點(diǎn)結(jié)構(gòu)體類型的指針
	struct SListNode* next; 

}SLTNode; //將struct SListNode重命名為SLTNode

//創(chuàng)建遍歷單鏈表的函數(shù):接收單鏈表結(jié)點(diǎn)的頭指針
void PrintSList(SLTNode* phead)
{
	//phead頭指針指向第一個(gè)結(jié)點(diǎn),
	//之后還要多次使用phead頭指針,
	//所以不要改變phead頭指針,
	//所以可以創(chuàng)建一個(gè)和phead頭指針一樣類型的指針cur代替phead頭指針
	SLTNode* cur = phead;

	//因?yàn)殒湵淼阶詈蠼Y(jié)點(diǎn)的指針域?yàn)镹ULL才結(jié)束
	//所以只要cur不為NULL就繼續(xù)遍歷結(jié)點(diǎn)進(jìn)行打?。?	while (cur != NULL)
	{
		//通過cur當(dāng)前指向的結(jié)點(diǎn)打印cur里數(shù)據(jù)域的內(nèi)容:
		printf("%d->", cur->data);

		//通過結(jié)點(diǎn)里指針域指向下一個(gè)結(jié)點(diǎn),方便打印下個(gè)結(jié)點(diǎn)的數(shù)據(jù)域內(nèi)容
		cur = cur->next;
	}

	//最后提示已指向NULL指針鏈表,遍歷結(jié)束:
	printf("NULL\n");
}

int main()
{
	//創(chuàng)建單鏈表結(jié)點(diǎn):
	SLTNode* n1 = (SLTNode*)malloc(sizeof(SLTNode));
	n1->data = 10; //在該結(jié)點(diǎn)數(shù)據(jù)域存放數(shù)據(jù)

	SLTNode* n2 = (SLTNode*)malloc(sizeof(SLTNode));
	n2->data = 20; //在該結(jié)點(diǎn)數(shù)據(jù)域存放數(shù)據(jù)


	SLTNode* n3 = (SLTNode*)malloc(sizeof(SLTNode));
	n3->data = 30; //在該結(jié)點(diǎn)數(shù)據(jù)域存放數(shù)據(jù)

	n1->next = n2; //n1的指針域指向結(jié)點(diǎn)n2
	n2->next = n3; //n2的指針域指向結(jié)點(diǎn)n3
	n3->next = NULL; //n3的指針域指向NULL(結(jié)束)

	PrintSList(n1); //調(diào)用函數(shù)打印單鏈表

	return 0;
}

*/


//包含鏈表頭文件:
#include "SList.h"

//測試函數(shù)1:測試--PrintSList、BuySListNode函數(shù)
void TestList1()
{
	int n; //存放鏈表長度

	//打印提示信息:
	printf("請輸入鏈表的長度:>");
	//接收鏈表長度
	scanf("%d", &n); 
	
	//打印提示信息:
	printf("\n請依次輸入每個(gè)結(jié)點(diǎn)的值:>");

	SLTNode* plist = NULL; //鏈表頭指針,一開始鏈表沒數(shù)據(jù)所以為NULL

	//使用for循環(huán),循環(huán)創(chuàng)建結(jié)點(diǎn)并賦值,形成鏈表:
	for (int i = 0; i < n; i++)
	{
		int val; //存放結(jié)點(diǎn)數(shù)據(jù)域數(shù)據(jù)
		scanf("%d", &val); //接收結(jié)點(diǎn)數(shù)據(jù)域數(shù)據(jù)
		
		//使用BuySListNode函數(shù)創(chuàng)建結(jié)點(diǎn)并給數(shù)據(jù)域賦值:
		SLTNode* newnode = BuySListNode(val);

		//頭插: 使用頭插把鏈表連接起來
		
		//把鏈表頭指針plist指向的頭結(jié)點(diǎn)地址賦給新創(chuàng)建結(jié)點(diǎn)的指針域next
		//這樣新結(jié)點(diǎn)的指針域next就能指向原來的頭結(jié)點(diǎn)地址
		newnode->next = plist;

		//再把新創(chuàng)建結(jié)點(diǎn)的地址賦給頭指針,
		//這樣頭指針就指向了新創(chuàng)建結(jié)點(diǎn)地址,讓其成為新的頭結(jié)點(diǎn)
		plist = newnode;
	}

	//使用PrintSList函數(shù)打印鏈表
	PrintSList(plist); //接收頭指針后打印


	//使用SLTPushBack函數(shù)手動(dòng)向鏈表尾部插入數(shù)據(jù)(尾插):
	SLTPushBack(plist, 10000);
	//再使用PrintSList函數(shù)打印插入后的鏈表
	PrintSList(plist);

	//plist和phead都是單鏈表頭指針,
	//但 plist是實(shí)參  phead是形參
	//phead 是 plist 的一份臨時(shí)拷貝
}

//測試函數(shù)2:測試--SLTPushBack、SLTPushFront函數(shù)
void TestList2()
{
	//創(chuàng)建單鏈表頭指針:
	SLTNode* plist = NULL;

	//使用尾插隨機(jī)插入幾個(gè)值: 
	//(此時(shí)頭指針指向NULL還沒有開辟空間創(chuàng)建結(jié)點(diǎn))
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);
	SLTPushBack(&plist, 5);
	  
	//使用頭插隨機(jī)插入幾個(gè)值:
	SLTPushFront(&plist, 10);
	SLTPushFront(&plist, 20);
	SLTPushFront(&plist, 30);
	SLTPushFront(&plist, 40);

	//使用SLTPrintf函數(shù)打印該鏈表:
	PrintSList(plist);
}

//測試函數(shù)3:測試--SLTPopBack(尾刪)函數(shù)
void TestList3()
{
	//創(chuàng)建單鏈表頭指針:
	SLTNode* plist = NULL;

	//使用尾插隨機(jī)插入幾個(gè)值: 
	//(此時(shí)頭指針指向NULL還沒有開辟空間創(chuàng)建結(jié)點(diǎn))
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("尾刪前鏈表:\n");
	PrintSList(plist);

	//使用尾刪函數(shù):
	SLTPopBack(&plist);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("尾刪后鏈表:\n");
	PrintSList(plist);

	SLTPopBack(&plist);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("尾刪后鏈表:\n");
	PrintSList(plist);

	SLTPopBack(&plist);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("尾刪后鏈表:\n");
	PrintSList(plist);

	SLTPopBack(&plist);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("尾刪后鏈表:\n");
	PrintSList(plist);

	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("尾刪后鏈表:\n");
	PrintSList(plist);
}

//測試函數(shù)4:測試--SLTPopFront(頭刪)函數(shù)
void TestList4()
{
	//創(chuàng)建單鏈表頭指針:
	SLTNode* plist = NULL;

	//使用尾插隨機(jī)插入幾個(gè)值: 
	//(此時(shí)頭指針指向NULL還沒有開辟空間創(chuàng)建結(jié)點(diǎn))
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("頭刪前鏈表:\n");
	PrintSList(plist);

	SLTPopFront(&plist);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("頭刪后鏈表:\n");
	PrintSList(plist);

	SLTPopFront(&plist);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("頭刪后鏈表:\n");
	PrintSList(plist);

	SLTPopFront(&plist);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("頭刪后鏈表:\n");
	PrintSList(plist);

	SLTPopFront(&plist);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("頭刪后鏈表:\n");
	PrintSList(plist);
}

//測試函數(shù)5:測試 -- SLTFind函數(shù)
void TestList5()
{
	//創(chuàng)建單鏈表頭指針:
	SLTNode* plist = NULL;

	//使用尾插隨機(jī)插入幾個(gè)值: 
	//(此時(shí)頭指針指向NULL還沒有開辟空間創(chuàng)建結(jié)點(diǎn))
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("操作前鏈表:\n");
	PrintSList(plist);

	//用SLTFind函數(shù)查找鏈表中數(shù)據(jù)域?yàn)?的結(jié)點(diǎn)的地址
	SLTNode* pos = SLTFind(plist, 1);
	if (pos != NULL)
	{	
		//找到了可以對該結(jié)點(diǎn)進(jìn)行修改
		pos->data *= 10;
		
		//所以SLTFind查找函數(shù)可以負(fù)責(zé)查找和修改的操作
	}

	printf("操作后鏈表:\n");
	PrintSList(plist);
}

//測試函數(shù)6:測試 -- SLTInsert函數(shù)
void TestList6()
{
	//創(chuàng)建單鏈表頭指針:
	SLTNode* plist = NULL;

	//使用尾插隨機(jī)插入幾個(gè)值: 
	//(此時(shí)頭指針指向NULL還沒有開辟空間創(chuàng)建結(jié)點(diǎn))
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("操作前鏈表:\n");
	PrintSList(plist);

	//用SLTFind函數(shù)查找鏈表中數(shù)據(jù)域?yàn)?的結(jié)點(diǎn)的地址
	SLTNode* pos = SLTFind(plist, 2);
	if (pos != NULL)
	{
		int x; //接收要插入的值
		scanf("%d", &x); //輸入要插入的值
		SLTInsert(&plist, pos, x); //在2前面插入x 
	}

	printf("操作后鏈表:\n");
	PrintSList(plist);
}

//測試函數(shù)7:測試 -- SLTInsertAfter函數(shù)
void TestList7()
{
	//創(chuàng)建單鏈表頭指針:
	SLTNode* plist = NULL;

	//使用尾插隨機(jī)插入幾個(gè)值: 
	//(此時(shí)頭指針指向NULL還沒有開辟空間創(chuàng)建結(jié)點(diǎn))
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("操作前鏈表:\n");
	PrintSList(plist);

	//用SLTFind函數(shù)查找鏈表中數(shù)據(jù)域?yàn)?的結(jié)點(diǎn)d的地址
	SLTNode* pos = SLTFind(plist, 2);
	if (pos != NULL)
	{
		int x; //接收要插入的值
		scanf("%d", &x); //輸入要插入的值
		SLTInsertAfter(pos, x); //在2后面插入x 
	}

	printf("操作后鏈表:\n");
	PrintSList(plist);
}

//測試函數(shù)8:測試 -- SLTErase函數(shù)
void TestList8()
{
	//創(chuàng)建單鏈表頭指針:
	SLTNode* plist = NULL;

	//使用尾插隨機(jī)插入幾個(gè)值: 
	//(此時(shí)頭指針指向NULL還沒有開辟空間創(chuàng)建結(jié)點(diǎn))
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("操作前鏈表:\n");
	PrintSList(plist);

	//用SLTFind函數(shù)查找鏈表中數(shù)據(jù)域?yàn)?的結(jié)點(diǎn)d的地址
	SLTNode* pos = SLTFind(plist, 2);
	if (pos != NULL)
	{
		int x; //接收要插入的值
		scanf("%d", &x); //輸入要插入的值
		SLTErase(&plist, pos); //刪除pos所在結(jié)點(diǎn)
		//pos結(jié)點(diǎn)指針刪除(釋放)后,要將其置為空:
		pos = NULL;
	}

	printf("操作后鏈表:\n");
	PrintSList(plist);
}

//測試函數(shù)9:測試 -- SLTEraseAfter函數(shù)
void TestList9()
{
	//創(chuàng)建單鏈表頭指針:
	SLTNode* plist = NULL;

	//使用尾插隨機(jī)插入幾個(gè)值: 
	//(此時(shí)頭指針指向NULL還沒有開辟空間創(chuàng)建結(jié)點(diǎn))
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("操作前鏈表:\n");
	PrintSList(plist);

	//用SLTFind函數(shù)查找鏈表中數(shù)據(jù)域?yàn)?的結(jié)點(diǎn)d的地址
	SLTNode* pos = SLTFind(plist, 2);
	if (pos != NULL)
	{
		int x; //接收要插入的值
		scanf("%d", &x); //輸入要插入的值
		SLTEraseAfter(pos); //刪除pos結(jié)點(diǎn)的下個(gè)結(jié)點(diǎn)
		//pos結(jié)點(diǎn)指針刪除(釋放)后,要將其置為空:
		pos = NULL;
	}

	printf("操作后鏈表:\n");
	PrintSList(plist);
}

//測試函數(shù)10:測試 -- SLTDestroy函數(shù)
void TestList10()
{
	//創(chuàng)建單鏈表頭指針:
	SLTNode* plist = NULL;

	//使用尾插隨機(jī)插入幾個(gè)值: 
	//(此時(shí)頭指針指向NULL還沒有開辟空間創(chuàng)建結(jié)點(diǎn))
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	//使用SLTPrintf函數(shù)打印該鏈表:
	printf("操作前鏈表:\n");
	PrintSList(plist);

	SLTDestroy(&plist);
}

//主函數(shù):
int main()
{
	//TestList1();
	//TestList2();
	//TestList3();
	//TestList4();
	//TestList5();
	//TestList6();
	//TestList7();
	//TestList8();
	//TestList9();
	TestList10();

	return 0;
}

到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn))的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)初階】八、非線性表里的二叉樹(二叉樹的實(shí)現(xiàn) -- C語言鏈?zhǔn)浇Y(jié)構(gòu))

    【數(shù)據(jù)結(jié)構(gòu)初階】八、非線性表里的二叉樹(二叉樹的實(shí)現(xiàn) -- C語言鏈?zhǔn)浇Y(jié)構(gòu))

    ========================================================================= 相關(guān)代碼gitee自取 : C語言學(xué)習(xí)日記: 加油努力 (gitee.com) ?========================================================================= 接上期 : 【數(shù)據(jù)結(jié)構(gòu)初階】七、非線性表里的二叉樹(堆的實(shí)現(xiàn) -- C語言順序結(jié)構(gòu))-CSDN博客 ?==========

    2024年02月08日
    瀏覽(31)
  • 數(shù)據(jù)結(jié)構(gòu)--隊(duì)列的鏈表實(shí)現(xiàn)

    數(shù)據(jù)結(jié)構(gòu)--隊(duì)列的鏈表實(shí)現(xiàn)

    初始化 判斷隊(duì)列是否為空 入隊(duì) 初始化 判斷隊(duì)列是否為空 入隊(duì) 隊(duì)滿 鏈?zhǔn)酱鎯?chǔ)――一般不會(huì)隊(duì)滿,除非內(nèi)存不足

    2024年02月11日
    瀏覽(25)
  • 【c++學(xué)習(xí)】數(shù)據(jù)結(jié)構(gòu)中的鏈表

    【c++學(xué)習(xí)】數(shù)據(jù)結(jié)構(gòu)中的鏈表

    鏈表與線性表相對,鏈表數(shù)據(jù)在內(nèi)存中的存儲(chǔ)空間是不連續(xù)的,鏈表每個(gè)節(jié)點(diǎn)包含數(shù)據(jù)域和指針域。 下述代碼實(shí)現(xiàn)了鏈表及其接口 包括增、刪、查、改以及其他一些簡單的功能 運(yùn)行結(jié)果: 于 2024-01-23 第一次整理編寫 學(xué)習(xí)時(shí)整理,不當(dāng)之處煩請指正 碼字不易,留個(gè)贊再走吧

    2024年01月24日
    瀏覽(29)
  • 【數(shù)據(jù)結(jié)構(gòu)】兩兩交換鏈表 && 復(fù)制帶隨機(jī)指針的鏈表

    【數(shù)據(jù)結(jié)構(gòu)】兩兩交換鏈表 && 復(fù)制帶隨機(jī)指針的鏈表

    給你一個(gè)鏈表,兩兩交換其中相鄰的節(jié)點(diǎn),并返回交換后鏈表的頭節(jié)點(diǎn)。你必須在不修改節(jié)點(diǎn)內(nèi)部的值的情況下完成本題(即,只能進(jìn)行節(jié)點(diǎn)交換)。 使用一個(gè)棧S來存儲(chǔ)相鄰兩個(gè)節(jié)點(diǎn)即可 給你一個(gè)長度為 n 的鏈表,每個(gè)節(jié)點(diǎn)包含一個(gè)額外增加的隨機(jī)指針 random ,該指針可以

    2024年04月15日
    瀏覽(100)
  • 數(shù)據(jù)結(jié)構(gòu):隊(duì)列的鏈表結(jié)構(gòu)(含完整代碼,可復(fù)制)

    1.輸出隊(duì)列 2.入隊(duì)一個(gè)元素 3.出隊(duì)一個(gè)元素 5.建立鏈表隊(duì)列 6.完整代碼

    2024年01月16日
    瀏覽(29)
  • 【數(shù)據(jù)結(jié)構(gòu)】[LeetCode138. 復(fù)制帶隨機(jī)指針的鏈表]

    【數(shù)據(jù)結(jié)構(gòu)】[LeetCode138. 復(fù)制帶隨機(jī)指針的鏈表]

    給你一個(gè)長度為? n ?的鏈表,每個(gè)節(jié)點(diǎn)包含一個(gè)額外增加的隨機(jī)指針? random ?,該指針可以指向鏈表中的任何節(jié)點(diǎn)或空節(jié)點(diǎn)。 構(gòu)造這個(gè)鏈表的? 深拷貝 。?深拷貝應(yīng)該正好由? n ?個(gè)? 全新 ?節(jié)點(diǎn)組成,其中每個(gè)新節(jié)點(diǎn)的值都設(shè)為其對應(yīng)的原節(jié)點(diǎn)的值。新節(jié)點(diǎn)的? next ?指針和

    2024年02月04日
    瀏覽(96)
  • 【數(shù)據(jù)結(jié)構(gòu)OJ題】復(fù)制帶隨機(jī)指針的鏈表

    【數(shù)據(jù)結(jié)構(gòu)OJ題】復(fù)制帶隨機(jī)指針的鏈表

    原題鏈接:https://leetcode.cn/problems/copy-list-with-random-pointer/description/ 目錄 1. 題目描述 2. 思路分析 3. 代碼實(shí)現(xiàn) 此題可以分三步進(jìn)行: 1. 拷貝鏈表的每一個(gè)結(jié)點(diǎn),拷貝的結(jié)點(diǎn)先鏈接到被拷貝結(jié)點(diǎn)的后面。 2. 復(fù)制隨機(jī)指針的鏈接:拷貝結(jié)點(diǎn)的隨機(jī)指針指向被拷貝結(jié)點(diǎn)隨機(jī)指針的下

    2024年02月12日
    瀏覽(310)
  • 利用C++超詳細(xì)解釋數(shù)據(jù)結(jié)構(gòu)中的鏈表

    鏈表(Linked List)是一種常見的數(shù)據(jù)結(jié)構(gòu),它可以動(dòng)態(tài)地插入和刪除元素,不需要像數(shù)組那樣預(yù)先分配固定大小的內(nèi)存。鏈表中的每個(gè)元素稱為節(jié)點(diǎn)(Node),每個(gè)節(jié)點(diǎn)包含一個(gè)數(shù)據(jù)值和一個(gè)指向下一個(gè)節(jié)點(diǎn)的指針。本教學(xué)將涵蓋以下知識(shí)點(diǎn): 單向鏈表(Singly Linked List) 雙向

    2024年02月04日
    瀏覽(27)
  • 【LeetCode】數(shù)據(jù)結(jié)構(gòu)題解(9)[復(fù)制帶隨機(jī)指針的鏈表]

    【LeetCode】數(shù)據(jù)結(jié)構(gòu)題解(9)[復(fù)制帶隨機(jī)指針的鏈表]

    所屬專欄:玩轉(zhuǎn)數(shù)據(jù)結(jié)構(gòu)題型?? ?? 博主首頁:初陽785?? ?? 代碼托管:chuyang785?? ?? 感謝大家的支持,您的點(diǎn)贊和關(guān)注是對我最大的支持?。?!?? ?? 博主也會(huì)更加的努力,創(chuàng)作出更優(yōu)質(zhì)的博文??!?? ?? 關(guān)注我,關(guān)注我,關(guān)注我,重要的事情說三遍?。。。?!

    2024年02月11日
    瀏覽(98)
  • 【數(shù)據(jù)結(jié)構(gòu)】LeetCode升級版的環(huán)形鏈表,復(fù)制帶隨機(jī)指針的鏈表

    【數(shù)據(jù)結(jié)構(gòu)】LeetCode升級版的環(huán)形鏈表,復(fù)制帶隨機(jī)指針的鏈表

    ? ? ? ? ? 1、題目說明 ? ? ? ? ? 2、題目解析 ? ? ? ? ??1、題目說明 ? ? ? ? ? 2、題目解析 ? ? ?1、題目說明 題目鏈接: 升級版的環(huán)形鏈表? 給定一個(gè)鏈表的頭節(jié)點(diǎn) head ,返回鏈表開始入環(huán)的第一個(gè)節(jié)點(diǎn)。? 如果鏈表無環(huán),則返回NULL。 如果鏈表中有某個(gè)節(jié)點(diǎn),可以通

    2024年01月16日
    瀏覽(101)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包