單鏈表是否相交(Java版),單鏈java

來源:互聯網
上載者:User

單鏈表是否相交(Java版),單鏈java
題目:有兩個帶頭結點的單鏈表L1,L2,判斷它們是否相交(它們中是否有相同的結點)

解題思路:
L1,L2中任何一個鏈表為空白它們不相交
因為單鏈表中可能有環,所以分3種情況討論
1、L1,L2中都沒有環,那麼可以通過判斷它們中最後一個結點是否相同,來判斷它們是否相交
2、L1,L2中一個有環,一個沒有環,那麼它們一定不相交

3、L1,L2中都有環,那麼只有當它們的環相同時,它們才相交,當它們在進入環之前有相同的結點時,它們交點的個數大於環中結點的個數,當它們進入環時才有第一個相同的結點時,它們交點的個數等于于環中結點的個數,這兩種情況下,都可以通過判斷它們環的入口結點是否相同來判斷它們是否相交。


ADT定義:

//單鏈表的結點類class LNode{//為了簡化訪問單鏈表,結點中的資料項目的存取權限都設為publicpublic int data;public LNode next;}

演算法實現:

public class LinkListUtli {// 判斷單鏈表是否有環public static boolean hasCircle(LNode L) {if (L == null)return false;// 單鏈表為空白時,單鏈表沒有環if (L.next == null)return false;// 單鏈表中只有頭結點,而且頭結點的next為空白,單鏈表沒有環LNode p = L.next;// p表示從頭結點開始每次往後走一步的指標LNode q = L.next.next;// q表示從頭結點開始每次往後走兩步的指標while (q != null) // q不為空白執行while迴圈{if (p == q)return true;// p與q相等,單鏈表有環p = p.next;q = q.next.next;}return false;}// 當單鏈表中沒有環時返回null,有環時返迴環的入口結點public static LNode searchEntranceNode(LNode L) {if (L == null)return null;// 單鏈表為空白時,單鏈表沒有環if (L.next == null)return null;// 單鏈表中只有頭結點,而且頭結點的next為空白,單鏈表沒有環LNode p = L.next;// p表示從頭結點開始每次往後走一步的指標LNode q = L.next.next;// q表示從頭結點開始每次往後走兩步的指標while (q != null) // q不為空白執行while迴圈{if (p == q)break;// p與q相等,單鏈表有環p = p.next;q = q.next.next;}if (q == null)return null;// 這裡之所以沒有向上面一樣,先讓p,q走一步再進入迴圈判斷,是因為頭結點可能就是環的入口結點q = L;while (q != null) {if (p == q)return p;// 返迴環中入口結點p = p.next;q = q.next;}return null;}    //判斷兩個單鏈表是否相交public static boolean isIntersect(LNode L1, LNode L2) {if (L1 == null || L2 == null)return false;// L1,L2中任何一個鏈表為空白它們不相交// L1,L2中都沒有環if (!(hasCircle(L1) || hasCircle(L2))) {LNode p = L1;LNode q = L2;while (p.next != null) {p = p.next;}while (q.next != null) {q = q.next;}if (p == q)return true;// 兩個無環單鏈表,最後一個結點相同時,它們相交return false;}// L1,L2中都有環else if (hasCircle(L1) && hasCircle(L2)) {if (searchEntranceNode(L1) == searchEntranceNode(L2))return true;// 兩個有環單鏈表,它們環的入口結點相同時,它們相交return false;}// L1,L2中一個有環,一個沒有環else {return false;// 兩個單鏈表,一個有環,一個無環,它們一定不相交}}}


拓展:有兩個帶頭結點的單鏈表L1,L2,判斷它們是否相交,並求出首次相交的結點


解題思路:
當L1與L2相交時,若L1與L2中都沒有環,那麼求出兩個單鏈表中結點個數之差的絕對值dCount,讓結點個數多的單鏈表從頭結點開始往下走dCount步,讓結點個數少的單鏈表從頭結點開始往後走,然後同時讓兩個單鏈表每次往後走一步,直到他們相等,那麼這個結點就是首次相交的結點。若L1與L2中都有環,求出單鏈表L1與L2從頭結點到環入口結點的結點總個數count,求出兩者之差的絕對值,讓count大的單鏈表從頭結點開始往下走dCount步,讓count大的的單鏈表從頭結點開始往後走,然後同時讓兩個單鏈表每次往後走一步,直到他們相等,那麼這個結點就是首次相交的結點。


演算法實現:

public class LinkListUtli {// 判斷單鏈表是否有環public static boolean hasCircle(LNode L) {if (L == null)return false;// 單鏈表為空白時,單鏈表沒有環if (L.next == null)return false;// 單鏈表中只有頭結點,而且頭結點的next為空白,單鏈表沒有環LNode p = L.next;// p表示從頭結點開始每次往後走一步的指標LNode q = L.next.next;// q表示從頭結點開始每次往後走兩步的指標while (q != null) // q不為空白執行while迴圈{if (p == q)return true;// p與q相等,單鏈表有環p = p.next;q = q.next.next;}return false;}// 當單鏈表中沒有環時返回null,有環時返迴環的入口結點public static LNode searchEntranceNode(LNode L) {if (L == null)return null;// 單鏈表為空白時,單鏈表沒有環if (L.next == null)return null;// 單鏈表中只有頭結點,而且頭結點的next為空白,單鏈表沒有環LNode p = L.next;// p表示從頭結點開始每次往後走一步的指標LNode q = L.next.next;// q表示從頭結點開始每次往後走兩步的指標while (q != null) // q不為空白執行while迴圈{if (p == q)break;// p與q相等,單鏈表有環p = p.next;q = q.next.next;}if (q == null)return null;// 這裡之所以沒有向上面一樣,先讓p,q走一步再進入迴圈判斷,是因為頭結點可能就是環的入口結點q = L;while (q != null) {if (p == q)return p;// 返迴環中入口結點p = p.next;q = q.next;}return null;}// 判斷兩個單鏈表是否相交public static boolean isIntersect(LNode L1, LNode L2) {if (L1 == null || L2 == null)return false;// L1,L2中任何一個鏈表為空白它們不相交// L1,L2中都沒有環if (!(hasCircle(L1) || hasCircle(L2))) {LNode p = L1;LNode q = L2;while (p.next != null) {p = p.next;}while (q.next != null) {q = q.next;}if (p == q)return true;// 兩個無環單鏈表,最後一個結點相同時,它們相交return false;}// L1,L2中都有環else if (hasCircle(L1) && hasCircle(L2)) {if (searchEntranceNode(L1) == searchEntranceNode(L2))return true;// 兩個有環單鏈表,它們環的入口結點相同時,它們相交return false;}// L1,L2中一個有環,一個沒有環else {return false;// 兩個單鏈表,一個有環,一個無環,它們一定不相交}}// 求兩個鏈表首次相交的結點public static LNode searchFirstIntersectNode(LNode L1, LNode L2) {if (isIntersect(L1, L2))return null;// 單鏈表L1與L2不相交時,返回nullif (!hasCircle(L1)) // L1中沒有環時,L1與L2中都沒有環{int count1 = 1;// 單鏈表L1中結點的個數,包括頭結點int count2 = 1;// 單鏈表L2中結點的個數,包括頭結點LNode p = L1;LNode q = L2;while (p.next != null) {p = p.next;count1++;}while (q.next != null) {q = q.next;count2++;}if (count1 >= count2)// 單鏈表L1比單鏈表L2長或兩者一樣長時{int dCount = count1 - count2;// 單鏈表L1比單鏈表L2多出的結點的個數p = L1;q = L2;while (dCount > 0) {p = p.next;}while (p != null) {if (p == q)return p;p = p.next;q = q.next;}} else {int dCount = count2 - count1;// 單鏈表L2比單鏈表L1多出的結點的個數p = L1;q = L2;while (dCount > 0) {q = q.next;}while (q != null) {if (p == q)return p;p = p.next;q = q.next;}}} else // L1有環時,此時L1與L2都有環{int count1 = 1;// 單鏈表L1中從頭結點到環的入口結點之間所有結點的個數,包括頭結點與環的入口結點int count2 = 1;// 單鏈表L2中從頭結點到環的入口結點之間所有結點的個數,包括頭結點與環的入口結點LNode p = L1;LNode q = L2;while (p != searchEntranceNode(L1)) {p = p.next;count1++;}while (q != searchEntranceNode(L2)) {q = q.next;count2++;}if (count1 >= count2)// 單鏈表L1比單鏈表L2從頭結點到環的入口結點之間所有結點的個數長或兩者一樣長時{int dCount = count1 - count2;// 單鏈表L1比單鏈表L2從頭結點到環的入口結點之間所有結點的個數多出的結點的個數p = L1;q = L2;while (dCount > 0) {p = p.next;}while (p != null) {if (p == q)return p;p = p.next;q = q.next;}} else {int dCount = count2 - count1;// 單鏈表L2比單鏈表L1從頭結點到環的入口結點之間所有結點的個數多出的結點的個數p = L1;q = L2;while (dCount > 0) {q = q.next;}while (q != null) {if (p == q)return p;p = p.next;q = q.next;}}}return null;}}




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.