#include <iostream>
#include <stack>
using namespace std;
//单向链表节点
struct ListNode{
int value;
struct ListNode *Next;
};
class MyList
{
public:
ListNode *Head1;
ListNode *Head2;
int len_Head1;
int len_Head2;
public:
MyList(){
Head1 = new ListNode;
Head2 = new ListNode;
len_Head1 = 1; //包含头部长度,所以为1
len_Head2 = 1;
}
~MyList(){
delete Head1;
Head1 = NULL;
delete Head2;
Head2 = NULL;
}
void creatlist();
bool isintersect1(); //是否相交(方法一)
ListNode * intersection_location(); //交点位置
bool isintersect2(); //是否相交(方法二)
};
void MyList::creatlist(){
ListNode *P1 = Head1;
//创建Head1的非公共节点部分
for(int i = 1;i<=2;i++){
ListNode *tmp1 = new ListNode;
tmp1->value = i;
tmp1->Next =NULL;
P1->Next = tmp1;
P1 = tmp1;
}
ListNode *P2 = Head2;
//创建Head2的非公共节点部分
for(int j = 1;j<=3;j++){
ListNode *tmp2 = new ListNode;
tmp2->value = j;
tmp2->Next =NULL;
P2->Next = tmp2;
P2 = tmp2;
}
//创建Head1和Head2的公共节点
for(int k = 1;k<=2;k++){
ListNode *tmp3 = new ListNode;
tmp3->value = k+10;
tmp3->Next =NULL;
P1->Next = tmp3;
P2->Next = tmp3;
P1 = tmp3;
P2 = tmp3;
}
}
//方法一:判断是否相交(如果两个链表相交,那么两个链表的尾结点的地址也是一样的,时间复杂度n)
bool MyList::isintersect1(){
ListNode *P1 = Head1;
ListNode *P2 = Head2;
while(P1->Next!=NULL){
P1 = P1->Next;
len_Head1++;
}
while(P2->Next!=NULL){
P2 = P2->Next;
len_Head2++;
}
if(P1==P2)
return true;
return false;
}
//求环节点:时间复杂度n
ListNode * MyList::intersection_location(){
ListNode *P1 = Head1;
ListNode *P2 = Head2;
int lendiff = 0;
if(len_Head1>=len_Head2){
lendiff = len_Head1 - len_Head2;
while(lendiff--){
P1 = P1->Next;
}
while(P1->Next!=NULL&&P2->Next!=NULL){
P1 = P1->Next;
P2 = P2->Next;
if(P1==P2)
return P1;
}
}else{
lendiff = len_Head2 - len_Head1;
while(lendiff--){
P2 = P2->Next;
}
while(P1->Next!=NULL&&P2->Next!=NULL){
P1 = P1->Next;
P2 = P2->Next;
if(P1==P2)
return P1;
}
}
}
//方法二:判断是否相交(将一个链表首尾相接,然后判断另外一个链表是否有环,如果有环,则两个链表相交)
bool MyList::isintersect2(){
ListNode *P1 = Head1;
ListNode *P2 = Head2;
while(P1->Next!=NULL){
P1 = P1->Next;
}
P1->Next = P2;
ListNode *slow = Head1;
ListNode *fast = Head1;
while(fast && fast->Next){
slow = slow->Next;
fast = fast->Next->Next;
if(slow==fast)
break;
}
//找出交点
if(fast!=NULL && fast->Next!=NULL){
cout<<"方法二相交"<<endl;
slow = Head1; //slow重新开始
while(slow!=fast){ //fast是第一次相交的点
slow = slow->Next;
fast = fast->Next;
}
cout<<"方法二交点的value : "<<fast->value<<endl;
return true;
}else{
cout<<"方法二不相交"<<endl;
}
return false;
}
int main ()
{
MyList *mylist = new MyList; //自己定义一个对象
mylist->creatlist();
bool isintersect = mylist->isintersect1();
cout<<"方法一:是否相交 :"<<isintersect<<endl;
if(isintersect==true){
ListNode *intersection_point = mylist->intersection_location();
cout<<"方法一交点的value : "<<intersection_point->value<<endl;
}
//方法二
mylist->isintersect2();
delete mylist;
mylist = NULL;
return 0;
}