题目
如何判断两个非空单向链表是否相交,如果相交返回该公共结点的地址,否则返回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