題目:給定鍊錶的頭指標和乙個結點指標,在o(1)時間刪除該結點。
函式的宣告如下:
void deletenode(listnode** plisthead, listnode* ptobedeleted);
分析:這是一道廣為流傳的google面試題,能有效考察我們的程式設計基本功,還能考察我們的反應速度,更重要的是,還能考察我們對時間複雜度的理解。
注意函式的第乙個引數plisthead是乙個指向指標的指標。例如,當我們往乙個空煉表中插入乙個結點時,新插入的結點就是鍊錶的頭指標。由於此時會改動頭指標,因此必須把phead引數設為指向指標的指標,否則出了這個函式phead仍然是乙個空指標。
在鍊錶中刪除乙個結點,最常規的做法是從鍊錶的頭結點開始,順序查詢要刪除的結點,找到之後再刪除。由於需要順序查詢,時間複雜度自然就是o(n) 了。
我們之所以需要從頭結點開始查詢要刪除的結點,是因為我們需要得到要刪除的結點的前面乙個結點。我們試著換一種思路。我們可以從給定的結點得到它的下乙個結點。這個時候我們實際刪除的是它的下乙個結點,由於我們已經得到實際刪除的結點的前面乙個結點,因此完全是可以實現的。當然,在刪除之前,我們需要需要把給定的結點的下乙個結點的資料拷貝到給定的結點中。此時,時間複雜度為o(1)。
上面的思路還有乙個問題:如果刪除的結點位於鍊錶的尾部,沒有下乙個結點,怎麼辦?我們仍然從鍊錶的頭結點開始,順便遍歷得到給定結點的前序結點,並完成刪除操作。
最後需要注意的是,如果鍊錶中只有乙個結點,而我們又要刪除鍊錶的頭結點,此時我們在刪除結點後,還需要把鍊錶的頭結點設定為null。
需要全面的考慮到刪除的結點位於鍊錶的尾部及輸入的鍊錶只有乙個結點的特殊情況。
這個時候時間複雜度是o(n)。那題目要求我們需要在o(1)時間完成刪除操作,我們的演算法是不是不符合要求?實際上,假設鍊錶總共有n個結點,我們的演算法在n-1總情況下時間複雜度是 o(1),只有當給定的結點處於鍊錶末尾的時候,時間複雜度為o(n)。那麼平均時間複雜度[(n-1)*o(1)+o(n)]/n,仍然為o(1)。
1實現**:void deletenode(listnode** plisthead, listnode*ptobedeleted)216
//鍊錶只有乙個結點,刪除頭結點(也是尾結點)
17else
if(*plisthead ==ptobedeleted)
1823
//鍊錶中有多個結點,刪除尾結點
24else
2531
32 pnode->m_pnext =null;
33delete ptobedeleted;
34 ptobedeleted =null;35}
36}3738 參考**
1 #include2using
namespace
std;
34 typedef struct
listnode
5listnode , *linklist;910
void insertlist(linklist &l , int data) //
頭插入11
2021
void printlist(linklist l) //
列印鍊錶
2229 cout<
3132
33void deletenode(linklist &l , listnode *ptobedeleted) //
刪除鍊錶l中的ptobedeleted結點
3447
//鍊錶只有乙個結點,刪除頭結點(也是尾結點)
48else
if(l ==ptobedeleted)
4954
//鍊錶中有多個結點,刪除尾結點
55else
5662 pnode->m_pnext =null;
63delete ptobedeleted;
64 ptobedeleted =null;
6566}67
}6869void
main()
70
96else
97deletenode(l, p);
9899 cout<
刪除後的鍊錶:
完整**:
在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 思路 在單向鍊錶中刪除乙個結點,最常用的做...
在O 1 時間刪除鍊錶結點
題目 題目 給定鍊錶的頭指標和乙個結點指標,在o 1 時間刪除該結點。思路 通常情況下,如果我們要刪除單鏈表的乙個節點,我們需要遍歷鍊錶找到這個節點的前乙個節點,然後執行刪除操作,時間複雜度為o n 我們試著換一種思路,事實上,我們可以從給定的結點得到它的下乙個結點。這個時候我們實際刪除的是它的下乙...