上一节聊了判断两个【无环】链表是否相交,那么如果相交,怎么找到相交结点呢?
题目
给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交
解题步骤
- 判断两个【无环】链表是否相交
- 找到两个【无环】链表的相交结点
- 判断链表是否带环
- 判断两个【有环】链表是否相交
- 找到两个【有环】链表的相交结点
思路
- 遍历的过程中记录链表的长度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"); }
前两篇讨论的前提都是链表是无环的,但是如果链表有环呢?下一篇,聊。