題目:給定鍊錶的頭指標和乙個結點指標,在
o(1)
時間刪除該結點。鍊錶結點的定義如下:
struct
listnode ;
函式的宣告如下:
void
deletenode
(listnode
* plisthead
, listnode
* ptobedeleted);
分析:這是一道廣為流傳的
面試題,能有效考察我們的程式設計基本功,還能考察我們的反應速度,更重要的是,還能考察我們對時間複雜度的理解。
在鍊錶中刪除乙個結點,最常規的做法是從鍊錶的頭結點開始,順序查詢要刪除的結點,找到之後再刪除。由於需要順序查詢,時間複雜度自然就是
o(n) 了。
我們之所以需要從頭結點開始查詢要刪除的結點,是因為我們需要得到要刪除的結點的前面乙個結點。我們試著換一種思路。我們可以從給定的結點得到它的下乙個結點。這個時候我們實際刪除的是它的下乙個結點,由於我們已經得到實際刪除的結點的前面乙個結點,因此完全是可以實現的。當然,在刪除之前,我們需要需要把給定的結點的下乙個結點的資料拷貝到給定的結點中。此時,時間複雜度為
o(1)。
上面的思路還有乙個問題:如果刪除的結點位於鍊錶的尾部,沒有下乙個結點,怎麼辦?我們仍然從鍊錶的頭結點開始,順便遍歷得到給定結點的前序結點,並完成刪除操作。這個時候時間複雜度是o(n)。
那題目要求我們需要在
o(1)
時間完成刪除操作,我們的演算法是不是不符合要求?實際上,假設鍊錶總共有n個
結點,我們的演算法在
n-1總情況下時間複雜度是
o(1)
,只有當給定的結點處於鍊錶末尾的時候,時間複雜度為
o(n)
。那麼平均時間複雜度
[(n-1)*o(1)+o(n)]/n
,仍然為
o(1)。
基於前面的分析,我們不難寫出下面的**。
參考**:
///
// delete a node in a list
// input: plisthead - the head of list
// ptobedeleted - the node to be deleted
///void deletenode(listnode* plisthead, listnode* ptobedeleted)
// if ptobedeleted is the last node in the list
else
// deleted ptobedeleted
pnode->m_pnext = null;
delete ptobedeleted;
ptobedeleted = null;
}}
O 1 時間刪除鍊錶結點
題目 給定單向鍊錶的頭指標和乙個結點指標,定義乙個函式在o 1 時間刪除該結點。鍊錶結點與函式的定義如下 typedef struct listnode node,pnode void delete node pnode plisthead,pnode ptodeleted 一般來說,我們拿到乙個刪...
在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 思路 在單向鍊錶中刪除乙個結點,最常用的做...