題目是這樣的:給你乙個單鏈表的表頭,再給你其中某個結點的指標,要你刪除這個結點,條件是你的程式必須在o(1)的時間內完成刪除。
由於有的同學對鍊錶還不是很熟悉,本文盡量描述的通俗易懂,老鳥請直接跳過前面一大段。
鍊錶結構如下:
struct node
;
題目不是很難,很快就能想到好辦法:)
首先回顧一下普通的刪除方法,首先通過表頭,找到待刪除結點(設為b)的前乙個結點(設為a),將a的指向改一下就行,然後刪除掉b結點就行了。要刪除的結點一定要delete掉,這不僅是個好習慣,而且能避免將來專案中可能造成的記憶體洩露的嚴重問題。
這個演算法主要耗時在於查詢前乙個結點,所以是o(n)的演算法。
那麼既然要求是o(1),顯然不能再去for一遍了,聯想到陣列的刪除,這個問題就比較好解決了。
首先我們很容易就能得到待刪除結點,即b結點的後乙個結點c,然後將c的值賦值給b結點的值,相當於陣列刪除時候的覆蓋,現在b結點和c結點一模一樣了,接下來就相當簡單了吧,我們不刪b,直接利用b刪掉c就行了,方法簡單,時間o(1)。
但是仔細想想這個演算法有個很明顯的缺陷,如果待刪除結點是最後乙個結點呢?這個時候似乎沒有什麼好的解決辦法,只能老老實實的o(n)了。現在我們來看看平均時間複雜度:
符合題目要求。
void deletenode_o1(node *linklist, node *p)
else // 如果p是末尾結點, 則找到p的前乙個結點然後正常刪除
}
最後附上完整測試**:
#includeusing namespace std;
struct node;
void createlinklist(node *linklist)}
void showlinklist(node * linklist)
void deletenode_on(node *linklist, node *p)
void deletenode_o1(node *linklist, node *p)
else // 如果p是末尾結點, 則找到p的前乙個結點然後正常刪除
} int main()
void deletenode(listnode** phead, listnode* ptobedeleted)
if (ptobedeleted->m_pnext != null)
else if (*phead ==ptobedeleted)
else
pnode->m_pnext = null;
delete ptobedeleted;
ptobedeleted = null; }}
void test(listnode* plisthead, listnode* pnode)
void test1()
刪除單鏈表節點O 1
一,題目 給定鍊錶的頭指標和乙個結點指標,在o 1 時間刪除該結點。鍊錶結點的定義如下 struct listnode 函式的宣告如下 void deletenode listnode plisthead,listnode ptobedeleted 二,分析 這是一道廣為流傳的google面試題,能...
在O 1 時間刪除單鏈表結點
出處 題目 給定單向鍊錶的頭指標和乙個結點指標,定義乙個函式在o 1 時間刪除該結點。原文採用的是c c 這裡採用c 節點定義如下 public class node 指標域 public nodenext publicnode publicnode t item 要實現的deletenode方法定...
在時間複雜度O 1 內刪除單鏈表節點
題目 給定單向鍊錶的頭指標和乙個節點指標,定義乙個函式在o 1 時間內刪除該節點。鍊錶節點定義如下 public class listnode分析 有三種情況 要刪除的節點不是尾節點,時間複雜度為o 1 單鏈表中只有乙個節點,刪除頭節點,時間複雜度為o 1 單鏈表中有多個節點,要刪除的為尾節點,時間...