1.判斷一個單鏈表是否有環,若是單鏈表有環,找出環的入口節點,計算環的長度函數
[1]判斷是否有環:指針
第一種方法:用兩個快慢指針,一個指針一次走一步,另外一個指針一次走兩步,若是存在環,則這兩個指針會在環內相遇。blog
第二種方法:遍歷鏈表時,記錄節點的地址,每次訪問一個節點,查找地址集合,若是找到表示有環。可使用map,把地址做爲key,訪問次數做爲value。編譯器
[2]環的入口點和環的長度:編譯
繼續用上面的快慢指針方法,設起點到環的起點距離爲a,環起點到兩個指針的交點距離爲b,環的長度爲r,慢指針走了s步,則快指針走了2s步,則:遍歷
a + b = smap
a + b + r = 2s方法
推導出r == s,a == r - b,所以在起點和交點設置兩個指針,開始遍歷,則一定相遇在環的起點位置,而且此時r == s,所以慢指針走的距離就是環的長度。im
2.判斷兩個單鏈表是否相交鏈表
第一種方法:把兩個鏈表遍歷後,每一個節點地址分別放到兩個棧裏面,比較棧頂的元素是否相同,若是相同表示相交。
第二種方法:把問題轉換爲單鏈表是否有環的問題,即先遍歷第一個鏈表到尾部,而後將尾部指向第二個鏈表的頭部,而後從第二個鏈表開始用兩個快慢指針遍歷,判斷是否有環,有環則表示相交。
這裏注意的是鏈接第二個鏈表後,理論應該從第一個鏈表頭部使用快慢指針判斷是否有環,可是其實不用,實際能夠從鏈表的任意的地方開始使用快慢指針遍歷判斷是否有環。
3.反轉單鏈表
第一種方法:設置一個新鏈表頭new_head = NULL,而後把以前的鏈表從頭遍歷插入到新鏈表上。由於從舊鏈表頭部遍歷,而且在新鏈表頭部插入,因此完成後即是反轉。
第二種方法:設置兩個指針,prev和next,prev記錄節點以前的位置(由於頭節點以前是NULL,因此prev初始爲NULL),next記錄節點以後的位置。這樣遍歷鏈表時,能夠放心的摘除節點,而後重置該節點的先後指針,遍歷執行即可以完成反轉。
4.inline關鍵字
首先頭文件中不但能夠包含inline函數,能夠包含普通函數。
inline發生在編譯階段,相似宏展開。inline只是給編譯器的建議,若是函數體過於複雜,編譯器也是會忽略的。
好處就是省掉了入棧和出棧操做,執行速度更快。