數據結構與算法面試題彙編(1)- 鏈表的操作與應用

1、給定單鏈表的頭指針和一個結點指針,在O(1)時間刪除該結點。

算法描述:刪除單鏈表的一個節點需要知道該節點的前驅和後繼。實際上找到前驅的平局時間複雜化度就是O(1).
傳送陣:http://blog.csdn.net/wcyoot/article/details/6426691

2、輸入一個單向鏈表,輸出該鏈表中倒數第k個結點。鏈表的倒數第0個結點爲鏈表的尾指針。

算法描述:定義兩個節點指針p1,p2,使p2-p1相距爲k,然後同步後移,當p2爲鏈表節點尾指針時,p1即爲倒數第k個節點。
傳送陣:http://blog.csdn.net/wcyoot/article/details/6428297

3、判斷一個單向鏈表是否有環。

算法描述:初始定義兩個指針p1,p2均指向鏈表頭,使其中一個步長爲1,另一個步長爲2。在到達鏈表尾節點前出現p1==p2,即該單鏈表有環。

4、尋找單向鏈表的環入口,即進入環的第一個節點。

算法描述:1)判斷該鏈表是否有環,即初始定義兩個指針p1,p2均指向鏈表頭,使其中一個步長爲1,另一個步長爲2。判斷在到達鏈表尾節點前出現p1==p2,如果不存在,則無環,如果存在,設p=p1.
2)設q爲鏈表頭節點,將q與p同時以步長爲1後移,當二者相同時,即爲環入口。
算法分析與源碼:http://blog.csdn.net/wcyoot/article/details/6426436

5、給定兩個單向鏈表,找出它們的第一個公共結點。

問題分析:1)如果他們存在公共節點,那麼第一個公共節點後的鏈接節點將是相同的;
2)需要判斷兩個單鏈表是否有環。
3)兩個鏈表中沒有環的算法:假設兩個鏈表的長度分別爲m,n,(m>=n),則將長鏈表的第m-n+1個節點與短鏈表的頭節點對齊,依次比較後繼節點,第一個相同的節點就是第一個公共節點。
算法描述:1)計算兩個鏈表的環入口,如果無環則環入口爲NULL;
2)如果兩個鏈表的環入口均爲NULL,則兩個鏈表均沒有環,按兩個鏈表均沒有環的算法處理;
3)如果兩個鏈表的環入口只有一個爲NULL,則兩個鏈表無公共交點;
4)如果兩個鏈表的環入口均不爲NULL,且相同,則將環入口作爲兩個鏈表的尾節點,按沒有換的兩個鏈表求第一公共節點處理
5)如果兩個鏈表的環入口均不爲NULL,且不同,則需要判斷一個鏈表的環入口是否在另一個鏈表的環上,如果不在,沒有公共節點,如果在,則可認爲任一環入口爲第一公共節點
算法具體分析與源碼:http://blog.csdn.net/wcyoot/article/details/6426436

6、複雜鏈表的複製

有一個複雜鏈表,其結點除了有一個m_pNext指針指向下一個結點外,還有一個m_pSibling指向鏈表中的任一結點或者NULL。其結點的C++定義如下:
struct ComplexNode
{
    int m_nValue;
    ComplexNode* m_pNext;
    ComplexNode* m_pSibling;
};                             
請完成函數ComplexNode* Clone(ComplexNode* pHead),以複製一個複雜鏈表。

算法分析:首先設原鏈表爲:a-b-c-d-e,接着插入新鏈表a-a'-b-b'-c-c'-d-d'-e-e',新節點中的m_pSibling全設爲NULL。第一遍完成以後,第二遍遍歷鏈表,更新a',b',c',d',e'的m_pSibling域(更新方法,以a'爲例,a'->m_pSibling=a'的前一個節點的m_pSibling->next)。第三遍把鏈表拆成兩個部分。算法複雜度o(N)

7、將一個二元查找樹轉換爲一個排序的雙向鏈表

問題描述:輸入一棵二元查找樹,將該二元查找樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只調整指針的指向。
算法分析:中序遍歷二元查找數的結果就是有序的目標節點順序。只需按中序遍歷的順序把節點鏈接到鏈表尾端即可。
傳送陣:http://blog.csdn.net/wcyoot/article/details/6428297

8、合併兩個有序的單向鏈表

問題分析:1)沒有說明兩個鏈表是否交叉,需要考慮這種情況
2)合併兩個不交叉的有序單向鏈表的算法:設排序規則爲G(x1, x2),同步遍歷兩個鏈表的遊標指針p1,p2,插入遊標p;如果滿足G(p1,p2)則將p1插入p後,p和p1後移;否則將p2插入p後,p和p2後移。如果p1,或p2有一個爲NULL,則將另一個指針後的所有元素插入到p後。
算法描述:設排序規則爲G(x1, x2),同步遍歷兩個鏈表的遊標指針p1,p2,插入遊標p;
1)初始化p1爲鏈表1的頭指針,p2爲鏈表2的頭指針,p=NULL;
2)如果p1==p2,則兩個鏈表存在公共點,p1後的所有節點相同,將p1後的所有節點鏈在p後,結束。
3)如果p1或p2有一個爲NULL,將非空的那個指針後的所有元素鏈在p後,結束
4)如果滿足G(p1,p2)則將p1插入p後,p和p1後移,否則將p2插入p後,p和p2後移;繼續步驟2)

9、單鏈表交換任意兩個節點(不含表頭)

算法描述:將兩個節點存儲的數據進行交換即可。不必真的交換節點。

10、用單鏈表模擬大整數加法運算

問題描述:例如:9>9>9>NULL + 1>NULL => 1>0>0>0>NULL
問題分析:設兩個鏈表A,B,求鏈表C,滿足C=A+B
算法一:將鏈表A和B反轉,將A和B相加合併。將進位加到下一節點,如果一個比較長,直接合並;如果最後有一個進位,在鏈表尾創建新的節點。最後將合併後的鏈表再次反轉。
算法二:求得鏈表A和B的長度,以遞歸的方式計算對應爲相加,如果有進位,在鏈表頭插入新建節點。

11、將二級單鏈表展開成一級單鏈表

問題描述:有個二級單鏈表,其中每個元素都含有一個指向一個單鏈表的指針。寫程序把這個二級鏈表展開成一級單鏈表。
/*這個二級單鏈表只包括一些head*/
public class Link
{   
    public Link Next;   
    public int Data;   
    public Link(Link next, int data)   
    {       
        this.Next = next;       
        this.Data = data;   
    }
}
public class CascadeLink
{
    public Link Next; 
    public CascadeLink NextHead;
    public CascadeLink(CascadeLink nextHead, Link next)
    {      
        this.Next = next;   
        this.NextHead = nextHead; 
    }
}

算法描述:遍歷,使A.Next的尾節點.Next = A.NextHead.Next.

12、單鏈表排序

算法分析:單鏈表元素交換有兩種:一、直接交換值;二、交換節點。並且單鏈表執行插入操作時不會引起數據移動。
傳送陣:參考http://blog.csdn.net/wcyoot/article/details/6427247

13、刪除單鏈表中重複的元素

算法描述:使用hashtable輔助,如果存在即刪除,如果不存在將值寫入hashtable。

14、刪除兩個雙向循環鏈表中值相同的節點。

算法描述:1)<key,value>的map對象m,其中key爲鏈表的值,value爲鏈表節點指針;遍歷雙向循環鏈表A,構造鍵值對寫入輔助對象m中
2)遍歷B,如果當前節點cur的值在map中存在,刪除cur節點並使cur後移,同時判斷m[cur.value]的值是否爲NULL,如果不爲空刪除其對應在A中的節點,並使m[cur.value]=NULL

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