標籤:鏈表 無環 相交點 資料結構 演算法
上一節聊了判斷兩個【無環】鏈表是否相交,那麼如果相交,怎麼找到相交結點呢?
題目
給出倆個單向鏈表的頭指標,比如 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;elsecout<<"無相交點"<<endl;system("pause");}
前兩篇討論的前提都是鏈表是無環的,但是如果鏈表有環呢?下一篇,聊。
C語言強化(七)鏈表相交問題_2 找到無環鏈表相交結點