C语言强化(七)链表相交问题_2 找到无环链表相交结点

上一节聊了判断两个【无环】链表是否相交,那么如果相交,怎么找到相交结点呢?


题目

给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交


解题步骤

  1. 判断两个【无环】链表是否相交
  2. 找到两个【无环】链表的相交结点
  3. 判断链表是否带环
  4. 判断两个【有环】链表是否相交
  5. 找到两个【有环】链表的相交结点
思路
  • 遍历的过程中记录链表的长度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");
}

前两篇讨论的前提都是链表是无环的,但是如果链表有环呢?下一篇,聊。

原文地址:https://www.cnblogs.com/javdroider/p/5184294.html