題目
如何判斷兩個非空單向鏈表是否相交,如果相交返回該公共結點的地址,否則返回NULL。
1.首先應該想出兩個鏈表怎樣纔能有公共結點(公共結點的位置可能出現在哪)。
2.分析求解思路:
補充:
(鏈表的結構定義如下,以下代碼皆爲java語言實現)
package com.algorithm.link;
public class Node {
Node next = null;//下一個結點
int data;//結點數據
public Node(int data){
this.data = data;
}
}
(1)首先判斷兩個鏈表是否相交,若相交,則返回true;否則返回false。
代碼如下:
/**
* 判斷兩個鏈表是否相交:
* 兩個鏈表相交,則它們的尾結點一定相同,
* 比較兩個鏈表的尾結點是否相同即可
*/
public boolean isCross(Node head1, Node head2){
Node temp1 = head1;
Node temp2 = head2;
while(temp1.next != null){
temp1 = temp1.next;
}
while(temp2.next != null){
temp2 = temp2.next;
}
if(temp1 == temp2){
return true;
}
return false;
}
(2)分別統計兩個鏈表結點個數,代碼如下:
public int link_length(Node head){
Node node1 = head;
int length = 0;
while(node1!=null)
{
length++;
node1=node1.next;
}
return length;
}
(3)返回公共結點中的起始結點,代碼實現如下:
/**
* 如果結點個數相同則用兩個指針分別從頭指針開始跑,
* 直至兩指針指向同一結點,返回地址;
* 如果結點個數不同則先用一個指針跑到自己合適的位置,
* 然後兩個指針一起跑直至指向同一結點,返回地址;
* 如果不相交則返回NULL。
* @param head1
* @param head2
* @return
*/
public Node find_First_Crossing(Node head1,Node head2){
Node temp1 = head1;
Node temp2 = head2;
if(!(is_Cross(head1,head2))){//如果不相交,則返回null.
return null;
}
else {
if (link_length(head1) >= link_length(head2)) {
int a = link_length(head1) - link_length(head2);
for (int i = 0; i < a; i++) {
temp1 = temp1.next;
}
while (temp1 != temp2) {
temp1 = temp1.next;
temp2 = temp2.next;
}
} else {
int b = link_length(head2) - link_length(head1);
for (int i = 0; i < b; i++) {
temp2 = temp2.next;
}
while (temp1 != temp2) {
temp1 = temp1.next;
temp2 = temp2.next;
}
}
}
return temp1;
}
(4)代碼測試如下:
因爲要做代碼測試,所以我們得提前構造兩個相交的鏈表,構造的方法也很簡單,兩個鏈表拼接一下即可構造。以下是我構造的連個鏈表,兩個鏈表均是拼接而成。
5—>3—>6—>8—>9—>25—>12(此爲第一個鏈表)
1—>2—>25—>12(此爲第二個鏈表)
相交!
true
相交的起始結點值爲:25