判断两个链表是否相交并求交点

链表是否相交分为以下三种情况:

1.两个单链表都不带环

2.只有一个单链表带环


3.两个单链表都带环


#pragma once
#include 
    
    
     
     
#include 
     
     
      
      

struct ListNode{
	int value;
	ListNode* next;
};

class CreateList
{
	typedef ListNode node;
public:
	CreateList()
		:root(NULL)
	{}
	void push(int data)
	{
		if (NULL == root)
		{
			node *temp = new node();
			temp->next =NULL;
			temp->value = data;
			root = temp;
		}
		else
		{
			node* temp = new node();
			node* tmp = root;
			while (tmp->next)
			{
				tmp = tmp->next;
			}
			tmp->next = temp;
			temp->value = data;
			temp->next = NULL;
		}
	}
	void PrintList()
	{
		node* tem = root;
		while (tem)
		{
			std::cout<
      
      
       
       value<<"->";
			tem = tem->next;
		}
		std::cout<<"NULL";
	}
	node* pHead()
	{
		return root;
	}
	int ListSize()
	{
		if (NULL == root)
		{
			return 0;
		}
		int count = 0;
		node* temp = root;
		while (NULL != temp)
		{
			count++;
			temp = temp->next;
		}
		return count;
	}
	
private:
	node* root;
};

bool JudgeIntersect(ListNode* n1, ListNode* n2)//判断不带环相交问题
{
	if (NULL == n1)
	{
		return false;
	}
	if (NULL == n2)
	{
		return false;
	}

	ListNode* t1 = n1;
	ListNode* t2 = n2;
	while(t1->next)
	{
		t1 = t1->next;
	}
	while (t2->next)
	{
		t2 = t2->next;
	}

	if (t2->value == t1->value)
	{
		return true;
	}
	return false;
}


//求相交点:
//1:拿一个链表中的每个节点和另一个链表中的所有节点作比较
//2:求出两个链表大小:让大的链表先走n步,然后一起走,每次比较是否相同
ListNode* FindIntersectNode(ListNode* n1, int s1, ListNode* n2, int s2)
{
	if ( NULL == n1 || NULL == n2)
	{
		return NULL;
	}
	int mid = 0;
	ListNode* tmp1 = n1;
	ListNode* tmp2 = n2;

	if (s1 != s2)
	{
		mid = s2 - s1;
		if (mid < 0)
		{
			mid = 0 - mid;
			while (mid != 0)
			{
				tmp1 = tmp1->next;
				mid--;
			}
		}else
		{
			while (mid != 0)
			{
				tmp2 = tmp2->next;
				mid--;
			}
		}
	}

	while (tmp1->next)
	{
		tmp1 = tmp1->next;
		tmp2 = tmp2->next;

		if (tmp1->value == tmp2->value)
		{
			return tmp1;
		}
	}

	return NULL;
}

//判断带环相交
//1.两个都带环,且在环外相交
//2.两个都带环,且在环内相交
ListNode* GetInNode(ListNode* p1)
{
	if (NULL == p1 || NULL == p1->next)
	{
		return NULL;
	}
	ListNode* lf = p1;
	ListNode* ls = p1;

	while (NULL != ls)
	{
		lf = lf->next;
		ls = ls->next->next;

		if (lf->value == ls->value)
		{
			break;
		}
	}
	ListNode* ph = p1;
	while (lf!= ph)
	{
		lf = lf->next;
		ph = ph->next;
	}

	return ph;
}

ListNode* GetIntersectNode(ListNode* plist1, ListNode* plist2)
{
	if (NULL == plist1 || NULL == plist2)
	{
		return NULL;
	}

	ListNode* pn1 = NULL;
	ListNode* pn2 = NULL;

	pn1 = GetInNode(plist1);
	pn2 = GetInNode(pn1);
	if (pn1 == pn2)
	{
		//环内相交
		//整个环都是交点
		return pn1;
	}else if(pn1 != pn2)
	{
		//环外相交
		int count1 = 0;
		int count2 = 0;
		ListNode* s1 = plist1;
		while (s1 != pn1)
		{
			count1++;
			s1 = s1->next;
		}
		ListNode* s2 = plist2;
		while (s2 != pn1)
		{
			count2++;
			s2 = s2->next;
		}
		return FindIntersectNode(plist1, count1, plist2, count2);

	}
}



#include "x.h"

int main()
{
	CreateList L;
	int ls;
	L.push(1);
	L.push(2);
	L.push(3);
	L.push(4);
	L.push(5);
	L.push(6);
	L.PrintList();
	ls = L.ListSize();
	std::cout<
       
       
        
        value<
        
        
       
       
      
      
     
     
    
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值