1.输入两个链表,找出他们的公共的结点
分析:
例如下面的两个链表,如果链表存在公共节点的话,则公共结点之后的所有结点都一样,两个链表的结尾结点是一样的。考虑到两个链表的长度不一样,如果两个指针分别同时指向链表的头节点,同时开始进行比较,这样显然不妥,因为如果两个链表存在公共结点的部分的话,则链表中存在后面一部分是重合的,这样的话可以先让长的链表的指针先走一定的长度,使得两个链表接下来比较的长度是一样的,这样每次两个链表的指针同时移动,如果存在公共的结点,则这两个指针的值就是相同的。
源码:
/**
* 功能说明:
* 作者:K0713
* 日期:2016-9-8
**/
#include<iostream>
using namespace std;
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
//创建结点
ListNode* CreateListNode(int value);
//连接两个结点
void ConnectListNodes(ListNode* pCurrent, ListNode* pNext);
//打印结点的值
void PrintListNode(ListNode* pNode);
//打印链表中的所有结点
void PrintList(ListNode* pHead);
//释放整个链表
void DestroyList(ListNode* pHead);
//释放单个结点
void DestroyNode(ListNode* pNode);
//练笔尾部添加结点
void AddToTail(ListNode** pHead, int value);
//删除指定的值的结点
void RemoveNode(ListNode** pHead, int value);
ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2);
unsigned int GetListLength(ListNode* pHead);
int main()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ListNode* pNode6 = CreateListNode(6);
ListNode* pNode7 = CreateListNode(7);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode6);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ListNode* resultNode = FindFirstCommonNode(pNode1, pNode4);
PrintList(pNode1);
PrintList(pNode4);
cout << "the result is:" << endl;
PrintListNode(resultNode);
//DestroyList(pNode1);//有公共结点的情况下不能采用这种方法来释放结点,因为公共的部分会存在释放两边的危险,导致内存异常
//DestroyList(pNode4);
DestroyNode(pNode1);
DestroyNode(pNode2);
DestroyNode(pNode3);
DestroyNode(pNode4);
DestroyNode(pNode5);
DestroyNode(pNode6);
DestroyNode(pNode7);
system("PAUSE");
return 0;
}
ListNode* CreateListNode(int value)
{
ListNode* pNode = new ListNode();
pNode->m_nValue = value;
pNode->m_pNext = NULL;
return pNode;
}
void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
{
if (pCurrent == NULL)
{
printf("Error to connect two nodes.\n");
exit(1);
}
pCurrent->m_pNext = pNext;
}
void PrintListNode(ListNode* pNode)
{
if (pNode == NULL)
{
cout<<"The node is NULL"<<endl;
}
else
{
cout << "The key in node is:" << pNode->m_nValue << endl;
}
}
void PrintList(ListNode* pHead)
{
cout << "PrintList starts." << endl;
ListNode* pNode = pHead;
while (pNode != NULL)
{
cout<<pNode->m_nValue<<" ";
pNode = pNode->m_pNext;
}
cout << endl << "PrintList ends" << endl;
}
void DestroyList(ListNode* pHead)
{
ListNode* pNode = pHead;
while (pNode != NULL)
{
pHead = pHead->m_pNext;
delete pNode;
pNode = pHead;
}
}
void DestroyNode(ListNode* pNode)
{
delete pNode;
pNode = NULL;
}
void AddToTail(ListNode** pHead, int value)
{
ListNode* pNew = new ListNode();
pNew->m_nValue = value;
pNew->m_pNext = NULL;
if (*pHead == NULL)
{
*pHead = pNew;
}
else
{
ListNode* pNode = *pHead;
while (pNode->m_pNext != NULL)
pNode = pNode->m_pNext;
pNode->m_pNext = pNew;
}
}
void RemoveNode(ListNode** pHead, int value)
{
if (pHead == NULL || *pHead == NULL)
return;
ListNode* pToBeDeleted = NULL;
if ((*pHead)->m_nValue == value)
{
pToBeDeleted = *pHead;
*pHead = (*pHead)->m_pNext;
}
else
{
ListNode* pNode = *pHead;
while (pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value)
pNode = pNode->m_pNext;
if (pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value)
{
pToBeDeleted = pNode->m_pNext;
pNode->m_pNext = pNode->m_pNext->m_pNext;
}
}
if (pToBeDeleted != NULL)
{
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}
ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2)
{
// 得到两个链表的长度
unsigned int nLength1 = GetListLength(pHead1);
unsigned int nLength2 = GetListLength(pHead2);
int nLengthDif = nLength1 - nLength2;//默认第一个链表长
ListNode* pListHeadLong = pHead1;
ListNode* pListHeadShort = pHead2;
if (nLength2 > nLength1)//如果第二个链表长,则更新
{
pListHeadLong = pHead2;
pListHeadShort = pHead1;
nLengthDif = nLength2 - nLength1;
}
// 先在长链表上走几步,再同时在两个链表上遍历
for (int i = 0; i < nLengthDif; ++i)
pListHeadLong = pListHeadLong->m_pNext;
while ((pListHeadLong != NULL) &&
(pListHeadShort != NULL) &&
(pListHeadLong != pListHeadShort))
{
pListHeadLong = pListHeadLong->m_pNext;
pListHeadShort = pListHeadShort->m_pNext;
}
// 得到第一个公共结点
ListNode* pFisrtCommonNode = pListHeadLong;
return pFisrtCommonNode;
}
unsigned int GetListLength(ListNode* pHead)
{
unsigned int nLength = 0;
ListNode* pNode = pHead;
while (pNode != NULL)
{
++nLength;
pNode = pNode->m_pNext;
}
return nLength;
}
结果: