给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。为了简化问题,我们假设俩个链表均不带环。
思路:首先即使带环也没关系,我们只需将环断开就又转换成了判断两个不带环的单向链表是否相交的问题,因此我们归根结底只需给出判断两个不带环的单向链表是否相交的算法即可。
因为单向链表的节点只有一个指向下一个节点的指针,因此如果两个单向链表相交,那么他们一定一定是成‘Y’型,即他们的最后一个节点一定一样的,则这样个问题就转换成判断两个单向链表的最后一个节点是否相等的问题,分析到这里,接下来写代码就是轻轻松松:
注意,这里我们使用的链表是有头节点的,如果题目要求是无头节点的链表,那么代码还需做一些改动,
首先给出链表节点的数据结构:
1 struct ListNode 2 { 3 int nData; 4 5 ListNode *next; 6 };
接下来判断链表是否相交的函数代码:
1 bool ListIntersect(ListNode *h1, ListNode *h2) 2 { 3 assert (h1 != NULL); 4 5 assert (h2 != NULL); 6 7 ListNode *h1_LastNode = h1->next; 8 ListNode *h2_LastNode = h2->next; 9 10 if ((NULL == h1_LastNode) || (NULL == h2_LastNode)) 11 { 12 return (false); 13 } 14 15 while (h1_LastNode->next != NULL) 16 { 17 h1_LastNode = h1_LastNode->next; 18 } 19 20 while (h2_LastNode->next != NULL) 21 { 22 h2_LastNode = h2_LastNode->next; 23 } 24 25 if (h1_LastNode == h2_LastNode) 26 { 27 return (true); 28 } 29 else 30 { 31 return (false); 32 } 33 }
为了测试,我们需要创建链表,这里简单的给出创建有头节点链表的方法
首先初始化头节点:
1 void InitializeListHeadNode(ListNode *&head) 2 { 3 if (NULL == (head = (ListNode *)malloc (sizeof (ListNode)))) 4 { 5 cout << "Fail to malloc space to root!\n"; 6 getch (); 7 } 8 9 head->next = NULL; 10 }
然后创建各个节点:
1 void CreateList(ListNode *head) 2 { 3 assert (head != NULL); 4 5 ListNode *pTemp = head; 6 7 int data; 8 9 cout << "输入链表节点值,-1结束: "; 10 cin >> data; 11 12 while (data != -1) 13 { 14 if (NULL == (pTemp->next = (ListNode *)malloc (sizeof (ListNode)))) 15 { 16 cout << "Fail to malloc space to pTemp->next!\n"; 17 getch (); 18 } 19 20 pTemp = pTemp->next; 21 pTemp->nData = data; 22 pTemp->next = NULL; 23 24 cin >> data; 25 } 26 }
还有比较重要的一点,使用完链表之后一定要释放动态申请的空间:
1 void FreeList(ListNode *&head) 2 { 3 ListNode *pTemp = head->next; 4 5 while (pTemp != NULL) 6 { 7 head->next = pTemp->next; 8 9 free (pTemp); 10 11 pTemp = head->next; 12 } 13 14 free (head); 15 head = NULL; 16 pTemp = NULL; 17 }
同时关于这个问题里面释放链表空间,若两个链表相交,就要注意不要重复的释放空间。