一,題目
給定鍊錶的頭指標和乙個結點指標,在
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)
。三,原始碼
[html]view plain
copy
print?
#include <
iostream
>
using namespace std;
struct node
; node *creat()
return head;
}
node *findlastnode(node *head,int data)
return head;
}
void deletenode(node *head,node *del)
else
}
void print(node *head)
}
int main()
#include using namespace std;
struct node
;node *creat()
return head;
} node *findlastnode(node *head,int data)
return head;
} void deletenode(node *head,node *del)
else
} void print(node *head) }
int main(){
node *head=creat();
print(head);
/*o(1)策略刪除乙個給定元素*/
node *del=findlastnode(head,8);
deletenode(head,del);
/*o(n)策略刪除結尾元素*/
node *del2=findlastnode(head,10);
deletenode(head,del2);
/*這種方法不可取*/
//delete last;
//last=null;
//cout<<"last :"值得注意的是,為了讓**看起來簡潔一些,上面的**基於兩個假設:(1
)給定的結點的確在鍊錶中;
不考慮第乙個假設對**的魯棒性是有影響的。(2
)給定的要刪除的結點不是鍊錶的頭結點。
至於第二個假設,當整個列表只有乙個結點時,**會有問題。但這個假設不算很過分,因為在有些鍊錶的實現中,會建立乙個虛擬的煉表頭,並不是乙個實際的鍊錶結點。這樣要刪除的結點就不可能是鍊錶的頭結點了。
O 1 時間複雜度刪除鍊錶元素
package lineartable 鍊錶節點類 class node 鍊錶類 public class linktable 增加節點 public void addnode node node end.next node 刪除節點 時間複雜度為o 1 無需遍歷鍊錶元素 public void d...
刪除鍊錶結點(時間複雜度為O 1 ))
題目 給定鍊錶的頭指標和乙個結點指標,在o 1 時間刪除該結點。鍊錶結點的定義如下 struct listnode 函式的宣告如下 void deletenode listnode plisthead,listnode ptobedeleted 分析 這是一道廣為流傳的google面試題,能有效考察...
以O 1 時間複雜度刪除鍊錶中的結點
剛看到這個題的時候我還琢磨,刪除鍊錶中的結點,我怎麼判斷這個結點就是這個鍊錶中的呢?如果判斷這個結點在鍊錶中就已經需要乙個掃瞄的時間了,就不可能以o 1 的複雜度了。所以這個題目應該改為,如何以o 1 時間複雜度刪除鍊錶中 已知 的結點,確保該結點存在。然後自己實現一遍 void deletenod...