出處:
題目:給定單向鍊錶的頭指標和乙個結點指標,定義乙個函式在o(1)時間刪除該結點。原文採用的是c/c++,這裡採用c#,節點定義如下:
public class node //指標域 public nodenext publicnode() publicnode(t item) }要實現的deletenode方法定義如下:
public static void deletenode(node headnode, nodedeletenode)在單向鍊錶中刪除乙個結點,最常規的做法無疑是從鍊錶的頭結點開始,順序遍歷查詢要刪除的結點,並在鍊錶中刪除該結點。這種思路由於需要順序查詢,時間複雜度自然就是o(n)。
是不是一定需要得到被刪除的結點的前乙個結點呢?答案是否定的。
我們可以很方便地得到要刪除的結點的一下結點。因此,我們可以把下乙個結點的內容複製到需要刪除的結點上覆蓋原有的內容,再把下乙個結點刪除,就相當於把當前需要刪除的結點刪除了。
但是,還有兩個特殊情況需要進行考慮:
(1)如果要刪除的結點位於鍊錶的尾部,那麼它就沒有下乙個結點:
此時我們仍然從鍊錶的頭結點開始,順序遍歷得到該結點的前序結點,並完成刪除操作,這仍然屬於o(n)時間的操作。
(2)如果鍊錶中只有乙個結點,而我們又要刪除鍊錶的頭結點(也是尾結點):
此時我們在刪除結點之後,還需要把鍊錶的頭結點設定為null。
最後,通過綜合最壞情況(尾節點需要順序查詢,1次)和最好情況(n-1次),因此平均時間複雜度為:
需要注意的是:受到o(1)時間的限制,我們不得不把確保結點在鍊錶中的責任推給了函式deletenode的呼叫者。
public static void deletenode(node headnode, nodedeletenode) if (deletenode.next != null) //鍊錶有多個節點,要刪除的不是尾節點:o(1)時間 else if (headnode == deletenode) //鍊錶只有乙個結點,刪除頭結點(也是尾結點):o(1)時間 else //鍊錶有多個節點,要刪除的是尾節點:o(n)時間 tempnode.next = null; deletenode = null; } }(1)封裝返回結果
該方法作為單元測試的對比方法,主要用來對比實際值與期望值是否一致:
public static string getprintnodes(nodeheadnode)測試通過結果://鍊錶中有多個結點,刪除尾結點 [testmethod] public voiddeletenodetest2() //鍊錶中有多個結點,刪除頭結點 [testmethod] public voiddeletenodetest3() //鍊錶中只有乙個結點,刪除頭結點 [testmethod] public voiddeletenodetest4() //鍊錶為空 [testmethod] public voiddeletenodetest5()
(3)**覆蓋率
面試題13 在O 1 時間刪除單鏈表結點
題目 給定單鏈表的頭指標和乙個結點指標,定義乙個函式在o 1 時間刪除節點。從頭開始順序遍歷單鏈表,遇到要刪除的節點跳過去就行了 因為已經給了要刪除節點的指標,可以找到待刪除節點的寫乙個節點的值,複製到待刪除節點,將該節點的next指標指向next.next就行了,流程如下 1 a b c d e ...
在O 1 時間刪除鍊錶結點
題目 給定單向鍊錶的頭指標和乙個結點指標,定義乙個函式在o 1 時間刪除該結點。鍊錶結點與函式的定義如下 struct listnode void deletenode listnode plisthead,listnode ptobedeleted 刪除結點的操作我們經常碰到,比如乙個鍊錶a b ...
在O 1 時間刪除鍊錶結點
問題描述 給定單向鍊錶的頭指標和乙個結點指標 定義乙個函式在o 1 時間刪除鍊錶結點。鍊錶結點與函式的定義如下 struct listnode void deletenode listnode plisthead listnode ptobedeleted 思路 在單向鍊錶中刪除乙個結點,最常用的做...