四道有趣的單鏈表面試題(轉)

原文:http://c.chinaitlab.com/ccjq/794824_2.html

鏈表也算是基本數據類型之一了。記得剛學習C語言的時候,鏈表和數組是見得最多的數據類型了。也正因爲它的常用,在面試的時候自然會有所涉及,本文 主要討論四道我覺得比較有趣的關於單鏈表的面試題。

  Q1  鏈表的反序

  Q2  找出鏈表的中間元素

  Q3  鏈表排序

  Q4  判斷一個單鏈表是否有環

  以下給出鏈表結點的數據結構:

  

  思路分析:

  單鏈表的一個比較大的特點用一句廣告語來說就是“不走回頭路”,不能實現隨機存取(random access)。如果我們想要找一個數組a的中間元素,直接a[len/2]就可以了,但是鏈表不行,因爲只有a[len/2 - 1] 知道a[len/2]在哪兒,其他人不知道。因此,如果按照數組的做法依樣畫葫蘆,要找到鏈表的中點,我們需要做兩步(1)知道鏈表有多長(2)從頭結點 開始順序遍歷到鏈表長度的一半的位置。這就需要1.5n(n爲鏈表的長度)的時間複雜度了。有沒有更好的辦法呢?有的。想法很簡單:兩個人賽跑,如果A的 速度是B的兩倍的話,當A到終點的時候,B應該剛到中點。這只需要遍歷一遍鏈表就行了,還不用計算鏈表的長度。

上面的代碼就體現了這個想法。

  Q3  鏈表排序

  思路分析:

  鏈表排序最好使用歸併排序算法。堆排序、快速排序這些在數組排序時性能非常好的算法,在鏈表只能“順序訪問”的魔咒下無法施展能力;但是歸併排 序卻如魚得水,非但保持了它O(nlogn)的時間複雜度,而且它在數組排序中廣受詬病的空間複雜度在鏈表排序中也從O(n)降到了O(1)。真是好得不 得了啊,哈哈。以上程序是遞推法的程序,另外值得一說的是看看那個時間複雜度,是不是有點眼熟?對!這就是分治法的時間複雜度,歸併排序又是divide and conquer。

  Q4  判斷一個單鏈表是否有環

  思路分析:

  這道題是《C專家編程》中的題了。其實算法也有很多,比如說:我覺得進行對訪問過的結點進行標記這個想法也不錯,而且在樹遍歷等場合我們也經常 使用。但是在不允許做標記的場合就無法使用了。在種種限制的條件下,就有了上面的這種算法,其實思想很簡單:就像兩個人在操場上跑步一樣,只要有個人的速 度比另一個人的速度快一點,他們肯定會有相遇的時候的。不過帶環鏈表與操場又不一樣,帶環鏈表的狀態是離散的,所以選擇走得快的要比走得慢的快多少很重 要。比如說這裏,如果一個指針一次走三步,一個指針一次走兩步的話,很有可能它們雖然在一個環中但是永遠遇不到,這要取決於環的大小以及兩個指針初始位置 相差多少了。呵呵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章