題目:給定鍊錶的頭指標和乙個結點指標,在o(1)時間刪除該結點。
函式的宣告如下:
void deletenode(listnode* plisthead, listnode* ptobedeleted);
分析:這是一道廣為流傳的google面試題,能有效考察我們的程式設計基本功,還能考察我們的反應速度,更重要的是,還能考察我們對時間複雜度的理解。
在鍊錶中刪除乙個結點,最常規的做法是從鍊錶的頭結點開始,順序查詢要刪除的結點,找到之後再刪除。由於需要順序查詢,時間複雜度自然就是o(n) 了。
我們之所以需要從頭結點開始查詢要刪除的結點,是因為我們需要得到要刪除的結點的前面乙個結點。我們試著換一種思路。我們可以從給定的結點得到它的下乙個結點。這個時候我們實際刪除的是它的下乙個結點,由於我們已經得到實際刪除的結點的前面乙個結點,因此完全是可以實現的。當然,在刪除之前,我們需要需要把給定的結點的下乙個結點的資料拷貝到給定的結點中。此時,時間複雜度為o(1)。
上面的思路還有乙個問題:如果刪除的結點位於鍊錶的尾部,沒有下乙個結點,怎麼辦?我們仍然從鍊錶的頭結點開始,順便遍歷得到給定結點的前序結點,並完成刪除操作。這個時候時間複雜度是o(n)。
那題目要求我們需要在o(1)時間完成刪除操作,我們的演算法是不是不符合要求?實際上,假設鍊錶總共有n個結點,我們的演算法在n-1總情況下時間複雜度是o(1),只有當給定的結點處於鍊錶末尾的時候,時間複雜度為o(n)。那麼平均時間複雜度[(n-1)*o(1)+o(n)]/n,仍然為o(1)。
#include using namespace std;
typedef struct lnodelnode, *list;
void insertlist(list &l, int data)//頭插入節點
void printlist(list l)//列印鍊錶
coutdelete tobedeleted ;
l=p;
} else
else//刪除節點時中間節點
}}void main()
{ list l=null;
lnode *p;
int n;
insertlist(l, 3);
insertlist(l, 7);
insertlist(l, 12);
insertlist(l, 56);
insertlist(l, 33);
insertlist(l, 78);
insertlist(l, 20);
insertlist(l, 89);
printlist(l);
cout<<"請輸入要刪除的節點:";
cin>>n;
p=l;
while(p->data!=n && p)
p=p->next;
if(!p)
{ cout<<"不存在這樣的節點!"<
面試題13 在O 1 時間內刪除鍊錶結點
題目 給定單向鍊錶的頭指標和乙個結點指標,定義乙個函式在o 1 時間刪除該結點。struct listnode 思路 如果按照常規方法,需要從頭指標開始遍歷,找到要刪除的節點指標的前乙個指標,使前乙個指標在指向要刪除結點的下乙個結點,則需要時間複雜度為o n 設要刪除的節點指標為i,結點指標順序為x...
在O 1 時間內刪除鍊錶節點
題目 給定單向鍊錶的頭指標和乙個節點指標,定義乙個函式在o 1 的時間刪除該節點。struct listnode void deletenode listnode plisthead,listnode ptobedeleted 演算法思路 一般我們是從頭節點開始遍歷,知道找到要刪除的節點的前面乙個節...
O 1 時間內刪除指定鍊錶結點
題目 給定單鏈表頭指標和乙個結點指標,定義乙個函式在o 1 時間內刪除該結點。分析 對於上圖例項鍊錶 a 刪除指標p有兩種方式 於是,定位到思路2,但是思路2有兩個特例 刪除的是尾指標,需要遍歷找到前乙個指標 整個鍊錶就乙個結點 屬於刪尾指標,但沒法找到前面的指標,需要開小灶單獨處理 大體演算法思路...