來源http://blog.csdn.net/huangxy10/article/details/8014233
只介紹O(n)算法
思路1:
將鏈表1中各結點地址存入HashTable中,
再遍歷鏈表2,如果有結點已經在HashTable中,則兩鏈表相交。
思路2:
將鏈表1的尾結點和鏈表2的首結點(注意不是頭結點)相連。
再判斷是否有環,如果有則兩鏈表相交。
思路3:(最簡單的方法)
判斷兩鏈表的尾結點是否爲同一結點,若是,則相交。
實現部分爲思路2。
- // LinkTable.cpp : 定義控制檯應用程序的入口點。
- //
- #include "stdafx.h"
- #include <iostream>
- #include <string>
- using namespace std;
- //鏈表的結構體
- struct node
- {
- char val;
- node * next;
- };
- //建立鏈表
- struct node * create( string & str_link )
- {
- int len = str_link.length();
- struct node * phead = new node(); //帶有表頭的鏈表,表頭中不存儲任何元素
- struct node * preNode = phead;
- for( int i=0; i<len; i++ )
- {
- struct node * pNode = new node();
- pNode->val = str_link[i];
- pNode->next = NULL;
- preNode->next = pNode;
- preNode = pNode;
- }
- return phead;
- }
- //輸出鏈表
- void out_link( struct node * phead )
- {
- if( phead == NULL )
- return;
- struct node * pNode = phead->next;
- while( pNode )
- {
- cout <<pNode->val;
- pNode = pNode->next;
- }
- cout << endl;
- }
- //找到第index個元素
- struct node * find_node(struct node* phead, int index )
- {
- if(!phead) return NULL;
- struct node * pNode = phead;
- while( index--)
- {
- pNode = pNode->next;
- if( !pNode )
- return NULL;
- }
- return pNode;
- }
- //檢查鏈表有無環
- //有,則返回快慢指針共同指向的點
- //無,則返回空指針
- struct node * check_loop( struct node * phead )
- {
- if(!phead)
- return NULL;
- struct node * pFast = phead;
- struct node * pSlow = phead;
- int step = 1;
- while( pFast )
- {
- pFast = pFast->next;
- if( step++%2==0 )
- {
- pSlow = pSlow->next;
- if( pSlow == pFast )
- return pSlow;
- }
- }
- return NULL;
- }
- //求兩個節點的距離,即中間有多少個連線
- //返回-1爲出錯,如果是同一節點,則返回0
- int find_length( struct node* pNode1, struct node* pNode2 )
- {
- if(!pNode1||!pNode2) return -1;
- int len=0;
- while( pNode1 )
- {
- if( pNode1 == pNode2 )
- return len;
- pNode1 = pNode1->next;
- len++;
- }
- return -1;
- }
- //找環的起始點,pTail爲快慢指針共同指向的節點
- struct node * loop_first_node( struct node * phead, struct node * pTail )
- {
- if( !phead || !pTail ) return NULL;
- struct node * pNode1 = pTail->next;
- struct node * pNode2 = phead->next;
- int M = find_length( pNode1, pTail );
- int N = find_length( pNode2, pTail );
- if( M > N )
- {
- int step = M-N;
- while(step--)
- pNode1 = pNode1->next;
- }
- if( N > M )
- {
- int step = N-M;
- while(step--)
- pNode2 = pNode2->next;
- }
- while(pNode1&&pNode2)
- {
- if(pNode1 == pNode2 )
- return pNode1;
- pNode1 = pNode1->next;
- pNode2 = pNode2->next;
- }
- return NULL;
- }
- void test()
- {
- string str;
- cin >> str;
- struct node *phead1 = create( str );
- int index;
- cin >> index;
- struct node * pNode1 = find_node( phead1, index );
- cin >> str;
- struct node *phead2 = create( str );
- struct node * pNode = phead2;
- while( pNode->next )
- pNode = pNode->next;
- pNode->next = pNode1; //生成相交鏈表, 註釋掉之一行則爲不相交
- while( pNode->next ) //找到鏈表1的尾結點
- pNode = pNode->next;
- pNode->next = phead2->next; //連接鏈表2的首結點
- struct node * pTail = check_loop( phead1 ); //檢查是否有環
- struct node * pFirstLoopNode = NULL;
- if( pTail )
- {
- cout <<"cross." <<endl;
- }
- else
- cout << "no cross." <<endl;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- test();
- return 0;
- }