两个链表第一个公共结点
Posted 三颗心
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两个链表第一个公共结点相关的知识,希望对你有一定的参考价值。
题目:输入两个链表,找出它们的第一个公共节点。链表的定义如下:
struct ListNode { int m_nValue; ListNode *m_pNext; };
思路1:采用蛮力的方法:在第一个链表上顺序遍历每个节点,每遍历到一个节点的时候,在第二个链表上顺序遍历每个节点。如果第二个链表上的节点和第一个链表上的节点一样,就说明两个链表在节点上重合,于是就找到了公共的节点。而通常蛮力并不是好的方法。
思路2:首先遍历两个链表得到它们的长度,就能知道哪个链表比较长,以及长的链表比短的链表多几个节点。在第二次遍历的时候,先在较长的节点上走若干步,接着同时在两个链表上遍历,找到的第一个相同的节点就是它们的公共的节点。
1 #include "stdafx.h" 2 #include<stdio.h> 3 #include<stdlib.h> 4 struct ListNode 5 { 6 int m_nValue; 7 ListNode* m_pNext; 8 }; 9 10 ListNode* CreateListNode(int value) 11 { 12 ListNode* pNode = new ListNode(); 13 pNode->m_nValue = value; 14 pNode->m_pNext = NULL; 15 16 return pNode; 17 } 18 19 void ConnectListNodes(ListNode* pCurrent, ListNode* pNext) 20 { 21 if(pCurrent == NULL) 22 { 23 printf("Error to connect two nodes.\\n"); 24 exit(1); 25 } 26 27 pCurrent->m_pNext = pNext; 28 } 29 30 void PrintListNode(ListNode* pNode) 31 { 32 if(pNode == NULL) 33 { 34 printf("The node is NULL\\n"); 35 } 36 else 37 { 38 printf("The key in node is %d.\\n", pNode->m_nValue); 39 } 40 } 41 42 void PrintList(ListNode* pHead) 43 { 44 printf("PrintList starts.\\n"); 45 46 ListNode* pNode = pHead; 47 while(pNode != NULL) 48 { 49 printf("%d\\t", pNode->m_nValue); 50 pNode = pNode->m_pNext; 51 } 52 53 printf("\\nPrintList end.\\n"); 54 } 55 56 void DestroyList(ListNode* pHead) 57 { 58 ListNode* pNode = pHead; 59 while(pNode != NULL) 60 { 61 pHead = pHead->m_pNext; 62 delete pNode; 63 pNode = pHead; 64 } 65 } 66 67 unsigned int GetListLength(ListNode* pHead); 68 69 ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) 70 { 71 // 得到两个链表的长度 72 unsigned int nLength1 = GetListLength(pHead1); 73 unsigned int nLength2 = GetListLength(pHead2); 74 int nLengthDif = nLength1 - nLength2; 75 76 ListNode* pListHeadLong = pHead1; 77 ListNode* pListHeadShort = pHead2; 78 if(nLength2 > nLength1) 79 { 80 pListHeadLong = pHead2; 81 pListHeadShort = pHead1; 82 nLengthDif = nLength2 - nLength1; 83 } 84 85 // 先在长链表上走几步,再同时在两个链表上遍历 86 for(int i = 0; i < nLengthDif; ++ i) 87 pListHeadLong = pListHeadLong->m_pNext; 88 89 while((pListHeadLong != NULL) && 90 (pListHeadShort != NULL) && 91 (pListHeadLong != pListHeadShort)) 92 { 93 pListHeadLong = pListHeadLong->m_pNext; 94 pListHeadShort = pListHeadShort->m_pNext; 95 } 96 97 // 得到第一个公共结点 98 ListNode* pFisrtCommonNode = pListHeadLong; 99 100 return pFisrtCommonNode; 101 } 102 103 unsigned int GetListLength(ListNode* pHead) 104 { 105 unsigned int nLength = 0; 106 ListNode* pNode = pHead; 107 while(pNode != NULL) 108 { 109 ++ nLength; 110 pNode = pNode->m_pNext; 111 } 112 113 return nLength; 114 } 115 116 // 第一个公共结点在链表中间 117 // 1 - 2 - 3 \\ 118 // 6 - 7 119 // 4 - 5 / 120 int main() 121 { 122 ListNode* pNode1 = CreateListNode(1); 123 ListNode* pNode2 = CreateListNode(2); 124 ListNode* pNode3 = CreateListNode(3); 125 ListNode* pNode4 = CreateListNode(4); 126 ListNode* pNode5 = CreateListNode(5); 127 ListNode* pNode6 = CreateListNode(6); 128 ListNode* pNode7 = CreateListNode(7); 129 130 ConnectListNodes(pNode1, pNode2); 131 ConnectListNodes(pNode2, pNode3); 132 ConnectListNodes(pNode3, pNode6); 133 ConnectListNodes(pNode4, pNode5); 134 ConnectListNodes(pNode5, pNode6); 135 ConnectListNodes(pNode6, pNode7); 136 137 ListNode* pResult = FindFirstCommonNode(pNode1, pNode4); 138 printf("%d\\n",pResult->m_nValue); 139 140 DestroyNode(pNode1); 141 DestroyNode(pNode2); 142 DestroyNode(pNode3); 143 DestroyNode(pNode4); 144 DestroyNode(pNode5); 145 DestroyNode(pNode6); 146 DestroyNode(pNode7); 147 148 return 0; 149 }
以上是关于两个链表第一个公共结点的主要内容,如果未能解决你的问题,请参考以下文章