日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

c++ 如何判断无效指针_如果链表中有环,我们应该如何判断?

發(fā)布時(shí)間:2025/3/20 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ 如何判断无效指针_如果链表中有环,我们应该如何判断? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


大四畢業(yè)前夕,計(jì)算機(jī)學(xué)院,

正在四處求職的小灰碰到了同系的學(xué)霸大黃......

小灰邊說邊回憶著上周去面試的情形......

有一個(gè)單向鏈表,鏈表當(dāng)中有可能出現(xiàn)“環(huán)”,就像下圖這樣。如何用程序判斷出這個(gè)鏈表是有環(huán)鏈表?

方法一:首先從頭節(jié)點(diǎn)開始,依次遍歷單鏈表的每一個(gè)節(jié)點(diǎn)。每遍歷到一個(gè)新節(jié)點(diǎn),就從頭節(jié)點(diǎn)重新遍歷新節(jié)點(diǎn)之前的所有節(jié)點(diǎn),用新節(jié)點(diǎn)ID和此節(jié)點(diǎn)之前所有節(jié)點(diǎn)ID依次作比較。如果發(fā)現(xiàn)新節(jié)點(diǎn)之前的所有節(jié)點(diǎn)當(dāng)中存在相同節(jié)點(diǎn)ID,則說明該節(jié)點(diǎn)被遍歷過兩次,鏈表有環(huán);如果之前的所有節(jié)點(diǎn)當(dāng)中不存在相同的節(jié)點(diǎn),就繼續(xù)遍歷下一個(gè)新節(jié)點(diǎn),繼續(xù)重復(fù)剛才的操作。

例如這樣的鏈表:A->B->C->D->B->C->D, 當(dāng)遍歷到節(jié)點(diǎn)D的時(shí)候,我們需要比較的是之前的節(jié)點(diǎn)A、B、C,不存在相同節(jié)點(diǎn)。這時(shí)候要遍歷的下一個(gè)新節(jié)點(diǎn)是B,B之前的節(jié)點(diǎn)A、B、C、D中恰好也存在B,因此B出現(xiàn)了兩次,判斷出鏈表有環(huán)。

假設(shè)從鏈表頭節(jié)點(diǎn)到入環(huán)點(diǎn)的距離是D,鏈表的環(huán)長(zhǎng)是S。那么算法的時(shí)間復(fù)雜度是0+1+2+3+....+(D+S-1) = (D+S-1)*(D+S)/2 , 可以簡(jiǎn)單地理解成 O(N*N)。而此算法沒有創(chuàng)建額外存儲(chǔ)空間,空間復(fù)雜度可以簡(jiǎn)單地理解成為O(1)。

方法二:首先創(chuàng)建一個(gè)以節(jié)點(diǎn)ID為鍵的HashSet集合,用來存儲(chǔ)曾經(jīng)遍歷過的節(jié)點(diǎn)。然后同樣是從頭節(jié)點(diǎn)開始,依次遍歷單鏈表的每一個(gè)節(jié)點(diǎn)。每遍歷到一個(gè)新節(jié)點(diǎn),就用新節(jié)點(diǎn)和HashSet集合當(dāng)中存儲(chǔ)的節(jié)點(diǎn)作比較,如果發(fā)現(xiàn)HashSet當(dāng)中存在相同節(jié)點(diǎn)ID,則說明鏈表有環(huán),如果HashSet當(dāng)中不存在相同的節(jié)點(diǎn)ID,就把這個(gè)新節(jié)點(diǎn)ID存入HashSet,之后進(jìn)入下一節(jié)點(diǎn),繼續(xù)重復(fù)剛才的操作。

這個(gè)方法在流程上和方法一類似,本質(zhì)的區(qū)別是使用了HashSet作為額外的緩存。

假設(shè)從鏈表頭節(jié)點(diǎn)到入環(huán)點(diǎn)的距離是D,鏈表的環(huán)長(zhǎng)是S。而每一次HashSet查找元素的時(shí)間復(fù)雜度是O(1), 所以總體的時(shí)間復(fù)雜度是1*(D+S)=D+S,可以簡(jiǎn)單理解為O(N)。而算法的空間復(fù)雜度還是D+S-1,可以簡(jiǎn)單地理解成O(N)。

等通知就是沒通知,這是職場(chǎng)上公認(rèn)的語(yǔ)言。

以上就是小灰悲劇的回憶......

方法三:首先創(chuàng)建兩個(gè)指針1和2(在java里就是兩個(gè)對(duì)象引用),同時(shí)指向這個(gè)鏈表的頭節(jié)點(diǎn)。然后開始一個(gè)大循環(huán),在循環(huán)體中,讓指針1每次向下移動(dòng)一個(gè)節(jié)點(diǎn),讓指針2每次向下移動(dòng)兩個(gè)節(jié)點(diǎn),然后比較兩個(gè)指針指向的節(jié)點(diǎn)是否相同。如果相同,則判斷出鏈表有環(huán),如果不同,則繼續(xù)下一次循環(huán)。

例如鏈表A->B->C->D->B->C->D,兩個(gè)指針最初都指向節(jié)點(diǎn)A,進(jìn)入第一輪循環(huán),指針1移動(dòng)到了節(jié)點(diǎn)B,指針2移動(dòng)到了C。第二輪循環(huán),指針1移動(dòng)到了節(jié)點(diǎn)C,指針2移動(dòng)到了節(jié)點(diǎn)B。第三輪循環(huán),指針1移動(dòng)到了節(jié)點(diǎn)D,指針2移動(dòng)到了節(jié)點(diǎn)D,此時(shí)兩指針指向同一節(jié)點(diǎn),判斷出鏈表有環(huán)。

此方法也可以用一個(gè)更生動(dòng)的例子來形容:在一個(gè)環(huán)形跑道上,兩個(gè)運(yùn)動(dòng)員在同一地點(diǎn)起跑,一個(gè)運(yùn)動(dòng)員速度快,一個(gè)運(yùn)動(dòng)員速度慢。當(dāng)兩人跑了一段時(shí)間,速度快的運(yùn)動(dòng)員必然會(huì)從速度慢的運(yùn)動(dòng)員身后再次追上并超過,原因很簡(jiǎn)單,因?yàn)榕艿朗黔h(huán)形的。

假設(shè)從鏈表頭節(jié)點(diǎn)到入環(huán)點(diǎn)的距離是D,鏈表的環(huán)長(zhǎng)是S。那么循環(huán)會(huì)進(jìn)行S次(為什么是S次,有心的同學(xué)可以自己揣摩下),可以簡(jiǎn)單理解為O(N)。除了兩個(gè)指針以外,沒有使用任何額外存儲(chǔ)空間,所以空間復(fù)雜度是O(1)。

問題一:判斷兩個(gè)單向鏈表是否相交,如果相交,求出交點(diǎn)。

問題二:在一個(gè)有環(huán)鏈表中,如何找出鏈表的入環(huán)點(diǎn)?

總結(jié)

以上是生活随笔為你收集整理的c++ 如何判断无效指针_如果链表中有环,我们应该如何判断?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。