如何在O 1 的時間裡刪除單鏈表的結點

2021-07-31 20:48:18 字數 1701 閱讀 4967

題目是這樣的:給你乙個單鏈表的表頭,再給你其中某個結點的指標,要你刪除這個結點,條件是你的程式必須在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 單鏈表中有多個節點,要刪除的為尾節點,時間...