(9)鍊錶追趕

2021-06-14 11:35:35 字數 3153 閱讀 2227

#include using namespace std;

// 認真分析具體情況,當把問題分析透了時,解決方案也就一目了然了

/* 1.如果兩個都沒有環:看結尾節點是否相同

2.如果乙個有環,乙個沒有,則必定分離

3.如果兩個都有環(node1,node2:分別是入環節點),看是否能從node1遍歷到node2

如果有環,且相交的話,則兩個鍊錶的環一定是相同的

*/void testlistcatch();

templatestruct node

node(t num) : val(num), next(null) };

/* 輸入乙個單向鍊錶,輸出該鍊錶中倒數第k個結點,

鍊錶的倒數第0個結點為鍊錶的尾指標

核心思想:兩個人的間距不變

*/templatenode*lastknode(node*head, int k);

// 初始化生成n個節點,並返回頭指標

templatenode*initnnode(unsigned n);

// 遍歷鍊錶

template void scanlist(node*head);

// 銷毀鍊錶

templatevoid destroylist(node*head);

/* 給出兩個鍊錶的頭指標h1、h2,判斷這兩個鍊錶是否相交。

這裡為了簡化問題,我們假設兩個鍊錶均不帶環

*/templatebool islistintersect(node*head1, node*head2);

/* 判斷是否有環:

設定兩個指標(p1, p2),初始值都指向頭,p1每次前進一步,p2每次前進二步,

如果鍊錶存在環,則p2先進入環,p1後進入環,兩個指標在環中走動,必定相遇

*/// 如果有環,則將交點放入intersectnode中,否則intersectnode為null

template bool islistcontainscircles(node*head, node* &intersectnode);

// 返回不包含環的鍊錶的最後乙個節點

template node* lastnode(node*head);

/* 求兩個鍊錶相交的第乙個節點

*//*

1.對於有環的:不確定

2.對於無環的:計數或hash

*//****

1.是否存在環

a)都包括環

i)判斷兩個入點是否相同

1)相同:返回入點

ii)不相同:不存在第乙個交點

b)乙個包含,乙個不包含

i)不存在第乙個交點

c)沒有環

i)hash

*****/

/* 特殊情況:

1.入環點相同,但是非環不相同

2.入環點相同,非環中,乙個包含另乙個

*//*

在一條左右水平放置的直線軌道上任選兩個點,放置兩個機械人,

請用如下指令系統為機械人設計控制程式,使這兩個機械人能夠在直線軌道上相遇

只包含4條指令,向左、向右、條件判定、無條件跳轉。

其中向左(右)指令每次能控制機械人向左(右)移動一步;

條件判定指令能對機械人所在的位置進行條件測試,測試結果是

如果對方機械人曾經到過這裡就返回true,否則返回false;

無條件跳轉,類似彙編裡面的跳轉,可以跳轉到任何地方

*//*

1.沒有考慮到這是乙個追趕問題:

兩個機械人都向同一方向移動,速度有快有慢

2.沒有考慮到不同指令所占用的執行時間不同

goonestep()

gotwostep()

*/

#include #include "9_listcatch.h"

void testlistcatch()

templatenode*initnnode(unsigned n)

return head;

}template void scanlist(node*head)

}templatevoid destroylist(node*head)

delete head;

}templatenode*lastknode(node*head, int k)

while (p2)

return p1;

}// 在某一處,兩個鍊錶指向了同乙個節點

/* 1.在每乙個節點儲存乙個資料,記錄被遍歷的次數。如果有被

遍歷兩次的,說明兩個鍊錶有交點.o(n)

2.hash表。

3.如果兩個相交,則不可能再分開,因此尾節點是相同的!

把眼光侷限在了第乙個交點上,而忽略了其他!

*/templatebool islistintersect(node*head1, node*head2)

else

}// 乙個有環,乙個沒有環:一定是分離的

eles if (head1containcircle != head2containcircle)

// 兩個都有環,則必定是乙個環

// 如果都帶環,判斷一煉表上倆指標相遇的那個節點,在不在另一條鍊錶上

// 即:通過乙個相遇的節點,能否到達另乙個相遇的交點

// 轉一圈

else

node*tmp = intersectnode1->next;

while (tmp != intersectnode1)

tmp = tmp->next;

} return false; }}

template bool islistcontainscircles(node*head, node* &intersectnode)

p2 = p2->next;

while (p1 && p2)

p1 = p1->next;

if (!p2->next)

p2 = p2->next;

if (!p2->next)

p2 = p2->next;

} return false;

}template node* lastnode(node*head)

return head;

}

鍊錶追趕問題

題目 輸入乙個單向鍊錶,輸出該鍊錶中倒數第k個結點,鍊錶的倒數第0個結點為鍊錶的尾指標 分析 首先這個鍊錶時單向鍊錶,並且我們也不知道鍊錶的長度,那麼僅僅憑藉乙個指標來找到倒數第k個節點,就需要知道鍊錶的長度,因此需要先遍歷整個鍊錶,得到鍊錶的長度過後,然後再從頭結點開始尋找,這種方法顯然很笨,那麼...

關於鍊錶追趕 鍊錶中環的問題

關於環的問題,介紹幾個個經典的題目 1.求鍊錶倒數第k個結點 最經典,最常見的解法就是,設定兩個指標p1,p2,一開始分別指向頭結點,首先p2先移動k個節點,之後開始p1,p2每次移動1個節點,直到p2達到最後乙個節點位置,那麼p1指向的就是倒數第k個節點。不過這種解法主要是針對單鏈表,且鍊錶中不存...

ACM模板(9)鍊錶

acm模板列表 目錄 一,鍊錶 二,獲取鍊錶長度 鍊錶反轉 鍊錶中倒數第k個節點 三,鍊錶合併 把兩個鍊錶交叉合併為乙個鍊錶 把兩個公升序的鍊錶合併為乙個公升序的鍊錶 四,鍊錶和結構體指標陣列互轉 鍊錶排序 五,判斷鍊錶是否有環 求煉錶環的長度 求煉錶環的第乙個節點 struct listtnode...