上一节聊了判断两个【无环】链表是否相交,那么如果相交,怎么找到相交结点呢?
题目
给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交
解题步骤
- 判断两个【无环】链表是否相交
- 找到两个【无环】链表的相交结点
- 判断链表是否带环
- 判断两个【有环】链表是否相交
- 找到两个【有环】链表的相交结点
思路
- 遍历的过程中记录链表的长度L1和L2(假设L1>L2)
- 遍历找到第一个链表中的第L1 - L2节点,
- 链表一从第L1-L2个节点开始遍历,链表二从第一个节点遍历,相当于两链表从与相交点距离相同的两个地点同时出发
- 每次前进一步
- 直到找到第一个相同的节点,则可以认为两个链表存在相交节点,
- 该点即为第一个相交节点
思路图解
源代码
#include <stdio.h>
#include<stdlib.h>
#include <iostream>
using namespace std;
/**
2.找到两个【无环】链表的相交结点
思路
遍历的过程中记录链表的长度L1和L2(假设L1>L2)
然后遍历找到第一个链表中的第L1 - L2节点,
然后链表一从第L1-L2个节点开始遍历,
链表二从第一个节点遍历,每次前进一步,
直到找到第一个相同的节点,则可以认为两个链表存在相交节点,
并且该点即为第一个相交节点
*/
/**
链表结构体
*/
struct ListNode{
int data;
ListNode * nextNode;
ListNode(ListNode * node,int value){
nextNode=node;
data=value;
}
};
ListNode * L1;
ListNode * L2;
/**
获取链表长度
*/
int getListLength(ListNode * head){
int i =0;
if(head==NULL)
return 0;
while(head->nextNode!=NULL){
head=head->nextNode;
i++;
}
return i;
}
/**
获取指定位置的链表结点
*/
ListNode * getThatListNode(ListNode * head,int pos){
int i =0;
if(head==NULL)
return NULL;
while(head->nextNode!=NULL){
head=head->nextNode;
i++;
if(pos==i)
return head;
}
return NULL;
}
/**
获取俩无环链表相交结点
L1:较长链表
L2:较短链表
*/
ListNode * getNoCircleListCrossNode(ListNode * L1,ListNode * L2){
ListNode * L_Long;
ListNode * L_Short;
int start;
int length1 = getListLength(L1);
int length2 = getListLength(L2);
if(length1>=length2){
L_Long=L1;
L_Short=L2;
start=length1-length2;
}else{
L_Long=L2;
L_Short=L1;
start=length2-length1;
}
L_Long=getThatListNode(L_Long,start);
while(L_Long->nextNode!=NULL&&L_Short->nextNode!=NULL){
if(L_Long==L_Short)
return L_Long;
L_Long=L_Long->nextNode;
L_Short=L_Short->nextNode;
}
return NULL;
}
//测试无环相交
void testCross(){
//相交段
ListNode * node = new ListNode(NULL,0);
node = new ListNode(node,1);
node = new ListNode(node,2);
node = new ListNode(node,3);
//在此处开始相交
L1 = new ListNode(node,11);
L2 = new ListNode(node,21);
//不相交段
L1 = new ListNode(L1,12);
L1 = new ListNode(L1,13);
L2 = new ListNode(L2,22);
L2 = new ListNode(L2,23);
L2 = new ListNode(L2,24);
L2 = new ListNode(L2,25);
}
void main()
{
testCross();
//int length1 = getListLength(L1);
//cout<<length1<<endl;
//ListNode * node = getThatListNode(L1, 3);
//cout<<node->data<<endl;
ListNode * node = getNoCircleListCrossNode(L1,L2);
if(node!=NULL)
cout<<node->data<<endl;
else
cout<<"无相交点"<<endl;
system("pause");
}
前两篇讨论的前提都是链表是无环的,但是如果链表有环呢?下一篇,聊。