鍊錶篇 鏈表面試題集

2021-06-09 13:34:51 字數 1897 閱讀 2960

1. 給定單鏈表,檢測是否有環。如果有環,則求出進入環的第乙個節點。

判斷單向鍊錶是否有環,可以採用快指標與慢指標的方式來解決。即定義乙個快指標fast和乙個慢指標slow,使得fast每次跳躍兩個節點,slow每次跳躍乙個節點。如果鍊錶沒有環的話,則slow與fast永遠不會相遇(這裡鍊錶至少有兩個節點);如果有環,則fast與slow將會在環中相遇。判斷出煉表有環以後,則需要算出進入環的第乙個節點。在fast與slow第一次相遇後,設定乙個節點pnode從鍊錶的頭部開始遍歷,每次只遍歷乙個節點。這樣,當fast與slow再次相遇時,pnode所處的位置便是環的首部。以下該問題的實現原始碼(c語言描述):

lnode* getloopnode(lnode* head)

//定義乙個快指標和乙個慢指標

lnode* fast = head;

lnode* slow = head;

while (fast && (fast->next))

}return slow;

} }return null;

}

2. 給定兩個單鏈表,檢測兩個鍊錶是否有交點,如果有返回第乙個交點。

檢測兩個單鏈表是否有交點是很容易的,因為如果兩個鍊錶有交點,那麼這兩個鍊錶的最後乙個節點必須相同,所以只需比較最後乙個節點即可。但是這種方案是無法求出第乙個交點的,所以需要另闢蹊徑。另外,判斷是否有交點可以轉換成鍊錶是否有環的問題。讓乙個鍊錶的最後乙個節點指向第二個鍊錶的頭結點,這樣的話,如果相交,則新的鍊錶是存在環的,並且交點便是環的入口點。

3. 只給定單鏈表中某個結點p(並非最後乙個結點,即p->next!=null)指標,刪除該結點。

由於沒有給定鍊錶的頭結點,所以無法獲取需要刪除節點的前驅結點,這樣就無法使用常規的方法去解決。在《程式設計之美》這本書裡面給出乙個非常精妙的解法,也就是採用了狸貓換太子的思想。以下是實現原始碼:

void deletenode(lnode* pnode)

//獲取pnode的後驅節點

lnode* qnode = pnode->next;

//將qnode的值賦給pnode,並刪除qnode

pnode->data = qnode->data;

pnode->next = qnode->next;

free(qnode);

}

4. 給定單鏈表頭結點,刪除鍊錶中倒數第k個結點

這個問題的關鍵是需要獲取倒數第k個節點。如何獲取呢?這裡,需要兩個指標p和q,p指向頭結點,q指向距離頭結點為k的節點。這樣p和q每次遍歷乙個節點,當q遍歷到末尾的時候,p指向的節點即為倒數第k個節點。然後刪除即可。以下是實現原始碼(這裡獲取的是倒數第k+1個節點,因為需要刪除的是倒數第k個節點):

void dellastknode(unsigned int k, lnode* head)

lnode* pnode = head;

lnode* qnode = head;

//將qnode遍歷到正數第k + 1個節點

unsigned int i;

for (i = 0; i < k; i++)

//獲取倒數第k + 1個節點

while (qnode->next)

//刪除倒數第k個節點

lnode* temp = pnode->next;

pnode->next = temp->next;

free(temp);

}

鏈表面試題集

1 鍊錶的反轉 注意 1 輸入的煉表頭指標為null或者整個鍊錶只有乙個結點時 2 反轉後鍊錶會不會斷裂 3 返回的反轉之後的頭節點是否為原始鍊錶的尾節點 2 鍊錶中環的入口結點 環中有4個節點,讓指標p1先走4步,然後指標p2和p1一起走,當p1走到入口節點,p2也與p1會相遇。就相當於,我要走9...

鍊錶及鏈表面試題

首先看一下順序表和煉表的優缺點,分別在什麼場景下使用?源 list.h ifndef list h define list h include include include typedef int datatype typedef struct node node,pnode,plist init...

鏈表面試題3 複雜鍊錶

struct clnode 複雜鍊錶 clnode,clpnode,cllist,clplist clpnode clbuynode datatype d clplist data d clplist next null clplist random null return clplist void...