《面试准备》C++链表操作2(判断两个单向链表是否相交,并得到交点)

#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;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值