C语言强化(七)链表相交问题_5 找到两个有环链表的相交结点

原创 2015年04月27日 09:08:44

有环链表是否相交我们也可以判断了,剩下的就是获得有环链表相交结点


题目

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



解题步骤

  1. 判断两个【无环】链表是否相交
  2. 找到两个【无环】链表的相交结点
  3. 判断链表是否带环
  4. 判断两个【有环】链表是否相交
  5. 找到两个【有环】链表的相交结点

思路:
显然,有环链表的相交点其实就是环的入口
如图


所以 问题转为求环的入口

直接上理论,具体解释不难,纯粹是一道小学数学追赶问题

若在头结点和快慢指针相遇结点分别设一指针,同步(单步)前进,则最后一定相遇在环入口结点

关于快慢指针的介绍,请参考链表相交问题第三节


创建函数:获得有环链表入口

/*
获得有环链表入口
	若在头结点和相遇结点分别设一指针,同步(单步)前进,
	则最后一定相遇在环入口结点
*/
ListNode * getCircleListEnter(ListNode * head){
	if(head==NULL)
		return NULL;
	ListNode * node = ifCircle(head);
	if(node==NULL)
		return NULL;
	while(node!=NULL&&head!=NULL){
		if(node==head)
			return node;
		node=node->nextNode;
		head=head->nextNode;
	}
	return NULL;
}

源代码

#include <stdio.h>
#include<stdlib.h>
#include <iostream>


using namespace std;

/**
5.找到两个【有环】链表的相交结点
思路
	即找两个入口点
	若在头结点和相遇结点分别设一指针,同步(单步)前进,
	则最后一定相遇在环入口结点
*/

/**
链表结构体
*/
struct ListNode{
	int data;
	ListNode * nextNode;
	ListNode(ListNode * node,int value){
		nextNode=node;
		data=value;
	}
};

ListNode * L1;
ListNode * L2;

/**
判断链表是否有环
node  链表头指针

方法:用两个指针,一个指针步长为1,一个指针步长为2,若最后相遇,则链表有环
有环 返回两指针相遇位置
无环 返回NULL
*/
ListNode * ifCircle(ListNode * node){
	if(NULL==node)
		return false;
	ListNode * fast = node;
	ListNode * slow = node;
	while(NULL!=fast&&NULL!=fast->nextNode){
		fast=fast->nextNode->nextNode;//步长为2
		slow=slow->nextNode;//步长为1
		if(fast==slow){
			cout<<"链表有环"<<endl;
			return fast;
		}
	}
	cout<<"链表无环"<<endl;
	return NULL;
}

/*判断结点是不是在链表上
head  链表头
node  结点
*/
bool ifNodeOnList(ListNode * head,ListNode * node){

	if(node==NULL)
		return 0;
	//为防止有环链表无限遍历,首先进行有无环判断
	ListNode * circleNode = ifCircle(head);
	int count = 0;//经过重复结点的次数
	while(head!=NULL&&count<2){
		if(head==node)
			return 1;
		if(head==circleNode)
			count++;
		head=head->nextNode;
	}
	return 0;
}

//判断有环链表是否相交
bool ifCircleListCross(ListNode * L1,ListNode * L2){
	ListNode * node = ifCircle(L1);
	if(node!=NULL)
		return ifNodeOnList(L2,node);
	return 0;
}

/*
获得有环链表入口
	若在头结点和相遇结点分别设一指针,同步(单步)前进,
	则最后一定相遇在环入口结点
*/
ListNode * getCircleListEnter(ListNode * head){
	if(head==NULL)
		return NULL;
	ListNode * node = ifCircle(head);
	if(node==NULL)
		return NULL;
	while(node!=NULL&&head!=NULL){
		if(node==head)
			return node;
		node=node->nextNode;
		head=head->nextNode;
	}
	return NULL;
}

//创建有环链表
ListNode * createCircleList(){
	ListNode * node = new ListNode(NULL,0);
	ListNode * enter = node;
	node = new ListNode(node,1);
	node = new ListNode(node,2);
	enter->nextNode=node;
	node = new ListNode(node,3);
	node = new ListNode(node,4);
	return node;
}

//创建有环链表相交
void createCircleListCross(){
	L1 = new ListNode(NULL,0);
	ListNode * enter2 = L1;//L2的入口
	L1 = new ListNode(L1,1);
	L1 = new ListNode(L1,2);
	enter2->nextNode=L1;//L1的入口
	L1 = new ListNode(L1,3);
	L1 = new ListNode(L1,4);

	L2 = new ListNode(enter2,0);
	L2 = new ListNode(L2,1);
	L2 = new ListNode(L2,2);
}


//创建有环链表不相交
void createCircleListNotCross(){
	L1=createCircleList();
	L2=createCircleList();
}

void main()
{
	createCircleListCross();
	ListNode * node = getCircleListEnter(L1);
	cout<<"有环链表L1的入口(相交点1)"<<node->data<<endl;
	node = getCircleListEnter(L2);
	cout<<"有环链表L2的入口(相交点2)"<<node->data<<endl;
	system("pause");
}

至此,这道古老的链表相交问题终于讲完了,总结下思路

判断链表是否带环(第三节

不带环,用不带环的方法,判断是否相交、求相交点(第一节第二节

带环,用带环的方法,判断是否相交、求相交点(第三节第四节


版权声明:本文为博主原创文章,未经博主允许不得转载。

编程之美:链表有环,如何判断相交

如果两个链表无换,判断是否相交很简单,判断两个环的最后一个节点指针是否相等即可。 题目描述:上面的问题都是针对链表无环的,那么如果现在,链表是有环的呢?上面的方法还同样有效么? 分析:如果...
  • gao1440156051
  • gao1440156051
  • 2016年06月16日 09:38
  • 803

【面试题】-判断两个单链表是否相交并求出相交的第一结点

问题描述判断两个单链表是否相交,如果相交,给出相交的第一个点(假设两个链表都不存在环)。相交的链表示意图如下所示。 解题思路方法一两个没有环的链表如果是相交于某一结点,如上图所示,这个结点后面都是共...
  • zwhlxl
  • zwhlxl
  • 2015年05月15日 15:53
  • 1459

判断两个单链表是否相交(链表中可能有环的情况下)

原文链接:http://www.cppblog.com/zengwei0771/articles/172700.html 题目描述:判断两个单链表是否相交,如果相交,给出相交的第一个点(链表中可能有...
  • yff1030
  • yff1030
  • 2013年02月18日 11:23
  • 2400

判断单链表是否有环,如果有找出环的入口位置=>求两个相交链表的交点

http://beyrens.blog.163.com/blog/static/9589445220081013332452/ 首先如何判断一个链表是否有环: 设置两个指针(fast, slow)...
  • gukesdo
  • gukesdo
  • 2012年04月26日 21:57
  • 2861

《编程之美》——编程判断两个链表是否相交

问题: 给出两个链表的头指针,判断这两个链表是否相交。假设两个链表均不带环。 分析与解法:【解法一】 如果两个链表都无环,则可以把第二个链表接在第一个链表后面,如果得到的链表有环,则说明这两个链...
  • zengzhen_CSDN
  • zengzhen_CSDN
  • 2015年11月10日 16:41
  • 904

Java代码 判断两个链表是否相交

题目:判断两个单向链表是否相交,假设两个链表均不存在环 算法思路:有两种方法,第一种方法就是在其中一个链表上顺序遍历每个节点,每遍历一个节点的时候,在另外一个链表上顺序遍历每个节点,如果便利过程中发...
  • yangmm2048
  • yangmm2048
  • 2015年04月07日 19:55
  • 1357

两个单链表相交问题

两个单链表相交,树中两个节点最近公共祖先
  • Li_Ning_
  • Li_Ning_
  • 2016年06月16日 18:51
  • 1241

判断两个链表是否相交并找出第一个相交节点

如何判断两个链表是否相交并找出第一个相交节点? ①相交的两个单链表要么均有环,要么都没有环 ②一个有环的单链表和一个无环的单链表不可能相交 一、什么是链表相交? 二、怎么判断两个链表是否相交? 三、怎...
  • Audience_
  • Audience_
  • 2017年08月28日 15:04
  • 177

判断两个无环链表是否相交,相交则返回相交首结点

/* 判断两个链表是否相交,相交则返回相交的结点 分为三种情况: 1:两个链表都没有环,方法是先分别求出两个链表的长度,然后让指向长链表的首指针先移动两链表长度的差值,然后同步移动,当相等时即为交点 ...
  • u011910350
  • u011910350
  • 2017年03月10日 17:46
  • 108

java 判断两个单链表是否相交

题目单链表可能有环,也可能无环。给定两个单链表的头节点 head1 和 head2, 这两个链表可能相交,也可能不相交。请实现一个函数,如果两个链表相交,请返回相交的第一个节点;如果不相交,返回 nu...
  • mccand1234
  • mccand1234
  • 2016年10月22日 15:05
  • 1214
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C语言强化(七)链表相交问题_5 找到两个有环链表的相交结点
举报原因:
原因补充:

(最多只允许输入30个字)