链表
目录:
18、【剑指Offer学习】【面试题18:在O(1)时间删除链表结点】
22、【剑指Offer学习】【面试题22:链表中倒数第k个结点】
23、【剑指Offer学习】【面试题23:链表中环的入口结点】
25、【剑指Offer学习】【面试题25:合并两个排序的链表】
36、【剑指Offer学习】【面试题36:二叉搜索树与双向链表】
52、【剑指Offer学习】【面试题52:两个链表的第一个公共结点】
6. 【剑指Offer学习】【面试题06:从尾到头打印链表】
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题6:从尾到头打印链表
// 题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。
#include "..\Utilities\List.h"
#include <stack>
void PrintListReversingly_Iteratively(ListNode* pHead)
{
std::stack<ListNode*> nodes;
ListNode* pNode = pHead;
while(pNode != nullptr)
{
nodes.push(pNode);
pNode = pNode->m_pNext;
}
while(!nodes.empty())
{
pNode = nodes.top();
printf("%d\t", pNode->m_nValue);
nodes.pop();
}
}
void PrintListReversingly_Recursively(ListNode* pHead)
{
if(pHead != nullptr)
{
if (pHead->m_pNext != nullptr)
{
PrintListReversingly_Recursively(pHead->m_pNext);
}
printf("%d\t", pHead->m_nValue);
}
}
// ====================测试代码====================
void Test(ListNode* pHead)
{
PrintList(pHead);
PrintListReversingly_Iteratively(pHead);
printf("\n");
PrintListReversingly_Recursively(pHead);
}
// 1->2->3->4->5
void Test1()
{
printf("\nTest1 begins.\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
Test(pNode1);
DestroyList(pNode1);
}
// 只有一个结点的链表: 1
void Test2()
{
printf("\nTest2 begins.\n");
ListNode* pNode1 = CreateListNode(1);
Test(pNode1);
DestroyList(pNode1);
}
// 空链表
void Test3()
{
printf("\nTest3 begins.\n");
Test(nullptr);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
return 0;
}
18. 面试题18:在O(1)时间删除链表结点
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题18(一):在O(1)时间删除链表结点
// 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该
// 结点。
#include <cstdio>
#include "..\Utilities\List.h"
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
if(!pListHead || !pToBeDeleted)
return;
// 要删除的结点不是尾结点
if(pToBeDeleted->m_pNext != nullptr)
{
ListNode* pNext = pToBeDeleted->m_pNext;
pToBeDeleted->m_nValue = pNext->m_nValue;
pToBeDeleted->m_pNext = pNext->m_pNext;
delete pNext;
pNext = nullptr;
}
// 链表只有一个结点,删除头结点(也是尾结点)
else if(*pListHead == pToBeDeleted)
{
delete pToBeDeleted;
pToBeDeleted = nullptr;
*pListHead = nullptr;
}
// 链表中有多个结点,删除尾结点
else
{
ListNode* pNode = *pListHead;
while(pNode->m_pNext != pToBeDeleted)
{
pNode = pNode->m_pNext;
}
pNode->m_pNext = nullptr;
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
}
// ====================测试代码====================
void Test(ListNode* pListHead, ListNode* pNode)
{
printf("The original list is: \n");
PrintList(pListHead);
printf("The node to be deleted is: \n");
PrintListNode(pNode);
DeleteNode(&pListHead, pNode);
printf("The result list is: \n");
PrintList(pListHead);
}
// 链表中有多个结点,删除中间的结点
void Test1()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
Test(pNode1, pNode3);
DestroyList(pNode1);
}
// 链表中有多个结点,删除尾结点
void Test2()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
Test(pNode1, pNode5);
DestroyList(pNode1);
}
// 链表中有多个结点,删除头结点
void Test3()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
Test(pNode1, pNode1);
DestroyList(pNode1);
}
// 链表中只有一个结点,删除头结点
void Test4()
{
ListNode* pNode1 = CreateListNode(1);
Test(pNode1, pNode1);
}
// 链表为空
void Test5()
{
Test(nullptr, nullptr);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
return 0;
}
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题18(二):删除链表中重复的结点
// 题目:在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复
// 结点被删除之后,链表如图3.4(b)所示。
#include <cstdio>
#include "../Utilities/list.h"
void DeleteDuplication(ListNode** pHead)
{
if(pHead == nullptr || *pHead == nullptr)
return;
ListNode* pPreNode = nullptr;
ListNode* pNode = *pHead;
while(pNode != nullptr)
{
ListNode *pNext = pNode->m_pNext;
bool needDelete = false;
if(pNext != nullptr && pNext->m_nValue == pNode->m_nValue)
needDelete = true;
if(!needDelete)
{
pPreNode = pNode;
pNode = pNode->m_pNext;
}
else
{
int value = pNode->m_nValue;
ListNode* pToBeDel = pNode;
while(pToBeDel != nullptr && pToBeDel->m_nValue == value)
{
pNext = pToBeDel->m_pNext;
delete pToBeDel;
pToBeDel = nullptr;
pToBeDel = pNext;
}
if(pPreNode == nullptr)
*pHead = pNext;
else
pPreNode->m_pNext = pNext;
pNode = pNext;
}
}
}
// ====================测试代码====================
void Test(char* testName, ListNode** pHead, int* expectedValues, int expectedLength)
{
if(testName != nullptr)
printf("%s begins: ", testName);
DeleteDuplication(pHead);
int index = 0;
ListNode* pNode = *pHead;
while(pNode != nullptr && index < expectedLength)
{
if(pNode->m_nValue != expectedValues[index])
break;
pNode = pNode->m_pNext;
index++;
}
if(pNode == nullptr && index == expectedLength)
printf("Passed.\n");
else
printf("FAILED.\n");
}
// 某些结点是重复的
void Test1()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(3);
ListNode* pNode5 = CreateListNode(4);
ListNode* pNode6 = CreateListNode(4);
ListNode* pNode7 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ListNode* pHead = pNode1;
int expectedValues[] = { 1, 2, 5 };
Test("Test1", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
DestroyList(pHead);
}
// 没有重复的结点
void Test2()
{
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, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ListNode* pHead = pNode1;
int expectedValues[] = { 1, 2, 3, 4, 5, 6, 7 };
Test("Test2", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
DestroyList(pHead);
}
// 除了一个结点之外其他所有结点的值都相同
void Test3()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(1);
ListNode* pNode4 = CreateListNode(1);
ListNode* pNode5 = CreateListNode(1);
ListNode* pNode6 = CreateListNode(1);
ListNode* pNode7 = CreateListNode(2);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ListNode* pHead = pNode1;
int expectedValues[] = { 2 };
Test("Test3", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
DestroyList(pHead);
}
// 所有结点的值都相同
void Test4()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(1);
ListNode* pNode4 = CreateListNode(1);
ListNode* pNode5 = CreateListNode(1);
ListNode* pNode6 = CreateListNode(1);
ListNode* pNode7 = CreateListNode(1);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ListNode* pHead = pNode1;
Test("Test4", &pHead, nullptr, 0);
DestroyList(pHead);
}
// 所有结点都成对出现
void Test5()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(2);
ListNode* pNode4 = CreateListNode(2);
ListNode* pNode5 = CreateListNode(3);
ListNode* pNode6 = CreateListNode(3);
ListNode* pNode7 = CreateListNode(4);
ListNode* pNode8 = CreateListNode(4);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ConnectListNodes(pNode7, pNode8);
ListNode* pHead = pNode1;
Test("Test5", &pHead, nullptr, 0);
DestroyList(pHead);
}
// 除了两个结点之外其他结点都成对出现
void Test6()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(2);
ListNode* pNode4 = CreateListNode(3);
ListNode* pNode5 = CreateListNode(3);
ListNode* pNode6 = CreateListNode(4);
ListNode* pNode7 = CreateListNode(5);
ListNode* pNode8 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ConnectListNodes(pNode7, pNode8);
ListNode* pHead = pNode1;
int expectedValues[] = { 2, 4 };
Test("Test6", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
DestroyList(pHead);
}
// 链表中只有两个不重复的结点
void Test7()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ConnectListNodes(pNode1, pNode2);
ListNode* pHead = pNode1;
int expectedValues[] = { 1, 2 };
Test("Test7", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
DestroyList(pHead);
}
// 结点中只有一个结点
void Test8()
{
ListNode* pNode1 = CreateListNode(1);
ConnectListNodes(pNode1, nullptr);
ListNode* pHead = pNode1;
int expectedValues[] = { 1 };
Test("Test8", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
DestroyList(pHead);
}
// 结点中只有两个重复的结点
void Test9()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(1);
ConnectListNodes(pNode1, pNode2);
ListNode* pHead = pNode1;
Test("Test9", &pHead, nullptr, 0);
DestroyList(pHead);
}
// 空链表
void Test10()
{
ListNode* pHead = nullptr;
Test("Test10", &pHead, nullptr, 0);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();
Test9();
Test10();
return 0;
}
22. 面试题22:链表中倒数第k个结点
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题22:链表中倒数第k个结点
// 题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,
// 本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,
// 从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是
// 值为4的结点。
#include <cstdio>
#include "..\Utilities\List.h"
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
if(pListHead == nullptr || k == 0)
return nullptr;
ListNode *pAhead = pListHead;
ListNode *pBehind = nullptr;
for(unsigned int i = 0; i < k - 1; ++ i)
{
if(pAhead->m_pNext != nullptr)
pAhead = pAhead->m_pNext;
else
{
return nullptr;
}
}
pBehind = pListHead;
while(pAhead->m_pNext != nullptr)
{
pAhead = pAhead->m_pNext;
pBehind = pBehind->m_pNext;
}
return pBehind;
}
// ====================测试代码====================
// 测试要找的结点在链表中间
void Test1()
{
printf("=====Test1 starts:=====\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 4.\n");
ListNode* pNode = FindKthToTail(pNode1, 2);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试要找的结点是链表的尾结点
void Test2()
{
printf("=====Test2 starts:=====\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 5.\n");
ListNode* pNode = FindKthToTail(pNode1, 1);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试要找的结点是链表的头结点
void Test3()
{
printf("=====Test3 starts:=====\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 1.\n");
ListNode* pNode = FindKthToTail(pNode1, 5);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试空链表
void Test4()
{
printf("=====Test4 starts:=====\n");
printf("expected result: nullptr.\n");
ListNode* pNode = FindKthToTail(nullptr, 100);
PrintListNode(pNode);
}
// 测试输入的第二个参数大于链表的结点总数
void Test5()
{
printf("=====Test5 starts:=====\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: nullptr.\n");
ListNode* pNode = FindKthToTail(pNode1, 6);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试输入的第二个参数为0
void Test6()
{
printf("=====Test6 starts:=====\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: nullptr.\n");
ListNode* pNode = FindKthToTail(pNode1, 0);
PrintListNode(pNode);
DestroyList(pNode1);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
return 0;
}
23. 面试题23:链表中环的入口结点
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题23:链表中环的入口结点
// 题目:一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中,
// 环的入口结点是结点3。
#include <cstdio>
#include "../Utilities/list.h"
ListNode* MeetingNode(ListNode* pHead)
{
if(pHead == nullptr)
return nullptr;
ListNode* pSlow = pHead->m_pNext;
if(pSlow == nullptr)
return nullptr;
ListNode* pFast = pSlow->m_pNext;
while(pFast != nullptr && pSlow != nullptr)
{
if(pFast == pSlow)
return pFast;
pSlow = pSlow->m_pNext;
pFast = pFast->m_pNext;
if(pFast != nullptr)
pFast = pFast->m_pNext;
}
return nullptr;
}
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode* meetingNode = MeetingNode(pHead);
if(meetingNode == nullptr)
return nullptr;
// 得到环中结点的数目
int nodesInLoop = 1;
ListNode* pNode1 = meetingNode;
while(pNode1->m_pNext != meetingNode)
{
pNode1 = pNode1->m_pNext;
++nodesInLoop;
}
// 先移动pNode1,次数为环中结点的数目
pNode1 = pHead;
for(int i = 0; i < nodesInLoop; ++i)
pNode1 = pNode1->m_pNext;
// 再移动pNode1和pNode2
ListNode* pNode2 = pHead;
while(pNode1 != pNode2)
{
pNode1 = pNode1->m_pNext;
pNode2 = pNode2->m_pNext;
}
return pNode1;
}
// ==================== Test Code ====================
void Test(char* testName, ListNode* pHead, ListNode* entryNode)
{
if(testName != nullptr)
printf("%s begins: ", testName);
if(EntryNodeOfLoop(pHead) == entryNode)
printf("Passed.\n");
else
printf("FAILED.\n");
}
// A list has a node, without a loop
void Test1()
{
ListNode* pNode1 = CreateListNode(1);
Test("Test1", pNode1, nullptr);
DestroyList(pNode1);
}
// A list has a node, with a loop
void Test2()
{
ListNode* pNode1 = CreateListNode(1);
ConnectListNodes(pNode1, pNode1);
Test("Test2", pNode1, pNode1);
delete pNode1;
pNode1 = nullptr;
}
// A list has multiple nodes, with a loop
void Test3()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode3);
Test("Test3", pNode1, pNode3);
delete pNode1;
pNode1 = nullptr;
delete pNode2;
pNode2 = nullptr;
delete pNode3;
pNode3 = nullptr;
delete pNode4;
pNode4 = nullptr;
delete pNode5;
pNode5 = nullptr;
}
// A list has multiple nodes, with a loop
void Test4()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode1);
Test("Test4", pNode1, pNode1);
delete pNode1;
pNode1 = nullptr;
delete pNode2;
pNode2 = nullptr;
delete pNode3;
pNode3 = nullptr;
delete pNode4;
pNode4 = nullptr;
delete pNode5;
pNode5 = nullptr;
}
// A list has multiple nodes, with a loop
void Test5()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode5);
Test("Test5", pNode1, pNode5);
delete pNode1;
pNode1 = nullptr;
delete pNode2;
pNode2 = nullptr;
delete pNode3;
pNode3 = nullptr;
delete pNode4;
pNode4 = nullptr;
delete pNode5;
pNode5 = nullptr;
}
// A list has multiple nodes, without a loop
void Test6()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
Test("Test6", pNode1, nullptr);
DestroyList(pNode1);
}
// Empty list
void Test7()
{
Test("Test7", nullptr, nullptr);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
return 0;
}
24. 面试题24:反转链表
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题24:反转链表
// 题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的
// 头结点。
#include <cstdio>
#include "..\Utilities\List.h"
ListNode* ReverseList(ListNode* pHead)
{
ListNode* pReversedHead = nullptr;
ListNode* pNode = pHead;
ListNode* pPrev = nullptr;
while(pNode != nullptr)
{
ListNode* pNext = pNode->m_pNext;
if(pNext == nullptr)
pReversedHead = pNode;
pNode->m_pNext = pPrev;
pPrev = pNode;
pNode = pNext;
}
return pReversedHead;
}
// ====================测试代码====================
ListNode* Test(ListNode* pHead)
{
printf("The original list is: \n");
PrintList(pHead);
ListNode* pReversedHead = ReverseList(pHead);
printf("The reversed list is: \n");
PrintList(pReversedHead);
return pReversedHead;
}
// 输入的链表有多个结点
void Test1()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ListNode* pReversedHead = Test(pNode1);
DestroyList(pReversedHead);
}
// 输入的链表只有一个结点
void Test2()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pReversedHead = Test(pNode1);
DestroyList(pReversedHead);
}
// 输入空链表
void Test3()
{
Test(nullptr);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
return 0;
}
25. 面试题25:合并两个排序的链表
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题25:合并两个排序的链表
// 题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按
// 照递增排序的。例如输入图3.11中的链表1和链表2,则合并之后的升序链表如链
// 表3所示。
#include <cstdio>
#include "..\Utilities\List.h"
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if(pHead1 == nullptr)
return pHead2;
else if(pHead2 == nullptr)
return pHead1;
ListNode* pMergedHead = nullptr;
if(pHead1->m_nValue < pHead2->m_nValue)
{
pMergedHead = pHead1;
pMergedHead->m_pNext = Merge(pHead1->m_pNext, pHead2);
}
else
{
pMergedHead = pHead2;
pMergedHead->m_pNext = Merge(pHead1, pHead2->m_pNext);
}
return pMergedHead;
}
// ====================测试代码====================
ListNode* Test(char* testName, ListNode* pHead1, ListNode* pHead2)
{
if(testName != nullptr)
printf("%s begins:\n", testName);
printf("The first list is:\n");
PrintList(pHead1);
printf("The second list is:\n");
PrintList(pHead2);
printf("The merged list is:\n");
ListNode* pMergedHead = Merge(pHead1, pHead2);
PrintList(pMergedHead);
printf("\n\n");
return pMergedHead;
}
// list1: 1->3->5
// list2: 2->4->6
void Test1()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode3);
ConnectListNodes(pNode3, pNode5);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode6 = CreateListNode(6);
ConnectListNodes(pNode2, pNode4);
ConnectListNodes(pNode4, pNode6);
ListNode* pMergedHead = Test("Test1", pNode1, pNode2);
DestroyList(pMergedHead);
}
// 两个链表中有重复的数字
// list1: 1->3->5
// list2: 1->3->5
void Test2()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode3);
ConnectListNodes(pNode3, pNode5);
ListNode* pNode2 = CreateListNode(1);
ListNode* pNode4 = CreateListNode(3);
ListNode* pNode6 = CreateListNode(5);
ConnectListNodes(pNode2, pNode4);
ConnectListNodes(pNode4, pNode6);
ListNode* pMergedHead = Test("Test2", pNode1, pNode2);
DestroyList(pMergedHead);
}
// 两个链表都只有一个数字
// list1: 1
// list2: 2
void Test3()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pMergedHead = Test("Test3", pNode1, pNode2);
DestroyList(pMergedHead);
}
// 一个链表为空链表
// list1: 1->3->5
// list2: 空链表
void Test4()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode3);
ConnectListNodes(pNode3, pNode5);
ListNode* pMergedHead = Test("Test4", pNode1, nullptr);
DestroyList(pMergedHead);
}
// 两个链表都为空链表
// list1: 空链表
// list2: 空链表
void Test5()
{
ListNode* pMergedHead = Test("Test5", nullptr, nullptr);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
return 0;
}
35. 面试题35:复杂链表的复制
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题35:复杂链表的复制
// 题目:请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复
// 制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个
// 结点外,还有一个m_pSibling 指向链表中的任意结点或者nullptr。
#include <cstdio>
#include "ComplexList.h"
void CloneNodes(ComplexListNode* pHead);
void ConnectSiblingNodes(ComplexListNode* pHead);
ComplexListNode* ReconnectNodes(ComplexListNode* pHead);
ComplexListNode* Clone(ComplexListNode* pHead)
{
CloneNodes(pHead);
ConnectSiblingNodes(pHead);
return ReconnectNodes(pHead);
}
void CloneNodes(ComplexListNode* pHead)
{
ComplexListNode* pNode = pHead;
while(pNode != nullptr)
{
ComplexListNode* pCloned = new ComplexListNode();
pCloned->m_nValue = pNode->m_nValue;
pCloned->m_pNext = pNode->m_pNext;
pCloned->m_pSibling = nullptr;
pNode->m_pNext = pCloned;
pNode = pCloned->m_pNext;
}
}
void ConnectSiblingNodes(ComplexListNode* pHead)
{
ComplexListNode* pNode = pHead;
while(pNode != nullptr)
{
ComplexListNode* pCloned = pNode->m_pNext;
if(pNode->m_pSibling != nullptr)
{
pCloned->m_pSibling = pNode->m_pSibling->m_pNext;
}
pNode = pCloned->m_pNext;
}
}
ComplexListNode* ReconnectNodes(ComplexListNode* pHead)
{
ComplexListNode* pNode = pHead;
ComplexListNode* pClonedHead = nullptr;
ComplexListNode* pClonedNode = nullptr;
if(pNode != nullptr)
{
pClonedHead = pClonedNode = pNode->m_pNext;
pNode->m_pNext = pClonedNode->m_pNext;
pNode = pNode->m_pNext;
}
while(pNode != nullptr)
{
pClonedNode->m_pNext = pNode->m_pNext;
pClonedNode = pClonedNode->m_pNext;
pNode->m_pNext = pClonedNode->m_pNext;
pNode = pNode->m_pNext;
}
return pClonedHead;
}
// ====================测试代码====================
void Test(const char* testName, ComplexListNode* pHead)
{
if(testName != nullptr)
printf("%s begins:\n", testName);
printf("The original list is:\n");
PrintList(pHead);
ComplexListNode* pClonedHead = Clone(pHead);
printf("The cloned list is:\n");
PrintList(pClonedHead);
}
// -----------------
// \|/ |
// 1-------2-------3-------4-------5
// | | /|\ /|\
// --------+-------- |
// -------------------------
void Test1()
{
ComplexListNode* pNode1 = CreateNode(1);
ComplexListNode* pNode2 = CreateNode(2);
ComplexListNode* pNode3 = CreateNode(3);
ComplexListNode* pNode4 = CreateNode(4);
ComplexListNode* pNode5 = CreateNode(5);
BuildNodes(pNode1, pNode2, pNode3);
BuildNodes(pNode2, pNode3, pNode5);
BuildNodes(pNode3, pNode4, nullptr);
BuildNodes(pNode4, pNode5, pNode2);
Test("Test1", pNode1);
}
// m_pSibling指向结点自身
// -----------------
// \|/ |
// 1-------2-------3-------4-------5
// | | /|\ /|\
// | | -- |
// |------------------------|
void Test2()
{
ComplexListNode* pNode1 = CreateNode(1);
ComplexListNode* pNode2 = CreateNode(2);
ComplexListNode* pNode3 = CreateNode(3);
ComplexListNode* pNode4 = CreateNode(4);
ComplexListNode* pNode5 = CreateNode(5);
BuildNodes(pNode1, pNode2, nullptr);
BuildNodes(pNode2, pNode3, pNode5);
BuildNodes(pNode3, pNode4, pNode3);
BuildNodes(pNode4, pNode5, pNode2);
Test("Test2", pNode1);
}
// m_pSibling形成环
// -----------------
// \|/ |
// 1-------2-------3-------4-------5
// | /|\
// | |
// |---------------|
void Test3()
{
ComplexListNode* pNode1 = CreateNode(1);
ComplexListNode* pNode2 = CreateNode(2);
ComplexListNode* pNode3 = CreateNode(3);
ComplexListNode* pNode4 = CreateNode(4);
ComplexListNode* pNode5 = CreateNode(5);
BuildNodes(pNode1, pNode2, nullptr);
BuildNodes(pNode2, pNode3, pNode4);
BuildNodes(pNode3, pNode4, nullptr);
BuildNodes(pNode4, pNode5, pNode2);
Test("Test3", pNode1);
}
// 只有一个结点
void Test4()
{
ComplexListNode* pNode1 = CreateNode(1);
BuildNodes(pNode1, nullptr, pNode1);
Test("Test4", pNode1);
}
// 鲁棒性测试
void Test5()
{
Test("Test5", nullptr);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
return 0;
}
36. 面试题36:二叉搜索树与双向链表
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题36:二叉搜索树与双向链表
// 题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求
// 不能创建任何新的结点,只能调整树中结点指针的指向。
#include <cstdio>
#include "..\Utilities\BinaryTree.h"
void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList);
BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree)
{
BinaryTreeNode *pLastNodeInList = nullptr;
ConvertNode(pRootOfTree, &pLastNodeInList);
// pLastNodeInList指向双向链表的尾结点,
// 我们需要返回头结点
BinaryTreeNode *pHeadOfList = pLastNodeInList;
while(pHeadOfList != nullptr && pHeadOfList->m_pLeft != nullptr)
pHeadOfList = pHeadOfList->m_pLeft;
return pHeadOfList;
}
void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList)
{
if(pNode == nullptr)
return;
BinaryTreeNode *pCurrent = pNode;
if (pCurrent->m_pLeft != nullptr)
ConvertNode(pCurrent->m_pLeft, pLastNodeInList);
pCurrent->m_pLeft = *pLastNodeInList;
if(*pLastNodeInList != nullptr)
(*pLastNodeInList)->m_pRight = pCurrent;
*pLastNodeInList = pCurrent;
if (pCurrent->m_pRight != nullptr)
ConvertNode(pCurrent->m_pRight, pLastNodeInList);
}
// ====================测试代码====================
void PrintDoubleLinkedList(BinaryTreeNode* pHeadOfList)
{
BinaryTreeNode* pNode = pHeadOfList;
printf("The nodes from left to right are:\n");
while(pNode != nullptr)
{
printf("%d\t", pNode->m_nValue);
if(pNode->m_pRight == nullptr)
break;
pNode = pNode->m_pRight;
}
printf("\nThe nodes from right to left are:\n");
while(pNode != nullptr)
{
printf("%d\t", pNode->m_nValue);
if(pNode->m_pLeft == nullptr)
break;
pNode = pNode->m_pLeft;
}
printf("\n");
}
void DestroyList(BinaryTreeNode* pHeadOfList)
{
BinaryTreeNode* pNode = pHeadOfList;
while(pNode != nullptr)
{
BinaryTreeNode* pNext = pNode->m_pRight;
delete pNode;
pNode = pNext;
}
}
void Test(char* testName, BinaryTreeNode* pRootOfTree)
{
if(testName != nullptr)
printf("%s begins:\n", testName);
PrintTree(pRootOfTree);
BinaryTreeNode* pHeadOfList = Convert(pRootOfTree);
PrintDoubleLinkedList(pHeadOfList);
}
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
void Test1()
{
BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
BinaryTreeNode* pNode14 = CreateBinaryTreeNode(14);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
BinaryTreeNode* pNode16 = CreateBinaryTreeNode(16);
ConnectTreeNodes(pNode10, pNode6, pNode14);
ConnectTreeNodes(pNode6, pNode4, pNode8);
ConnectTreeNodes(pNode14, pNode12, pNode16);
Test("Test1", pNode10);
DestroyList(pNode4);
}
// 5
// /
// 4
// /
// 3
// /
// 2
// /
// 1
void Test2()
{
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
ConnectTreeNodes(pNode5, pNode4, nullptr);
ConnectTreeNodes(pNode4, pNode3, nullptr);
ConnectTreeNodes(pNode3, pNode2, nullptr);
ConnectTreeNodes(pNode2, pNode1, nullptr);
Test("Test2", pNode5);
DestroyList(pNode1);
}
// 1
// \
// 2
// \
// 3
// \
// 4
// \
// 5
void Test3()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
ConnectTreeNodes(pNode1, nullptr, pNode2);
ConnectTreeNodes(pNode2, nullptr, pNode3);
ConnectTreeNodes(pNode3, nullptr, pNode4);
ConnectTreeNodes(pNode4, nullptr, pNode5);
Test("Test3", pNode1);
DestroyList(pNode1);
}
// 树中只有1个结点
void Test4()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
Test("Test4", pNode1);
DestroyList(pNode1);
}
// 树中没有结点
void Test5()
{
Test("Test5", nullptr);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
return 0;
}
52. 面试题52:两个链表的第一个公共结点
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题52:两个链表的第一个公共结点
// 题目:输入两个链表,找出它们的第一个公共结点。
#include <cstdio>
#include "..\Utilities\List.h"
unsigned int GetListLength(ListNode* pHead);
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 != nullptr) &&
(pListHeadShort != nullptr) &&
(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 != nullptr)
{
++nLength;
pNode = pNode->m_pNext;
}
return nLength;
}
// ====================测试代码====================
void DestroyNode(ListNode* pNode);
void Test(char* testName, ListNode* pHead1, ListNode* pHead2, ListNode* pExpected)
{
if(testName != nullptr)
printf("%s begins: ", testName);
ListNode* pResult = FindFirstCommonNode(pHead1, pHead2);
if(pResult == pExpected)
printf("Passed.\n");
else
printf("Failed.\n");
}
// 第一个公共结点在链表中间
// 1 - 2 - 3 \
// 6 - 7
// 4 - 5 /
void Test1()
{
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);
Test("Test1", pNode1, pNode4, pNode6);
DestroyNode(pNode1);
DestroyNode(pNode2);
DestroyNode(pNode3);
DestroyNode(pNode4);
DestroyNode(pNode5);
DestroyNode(pNode6);
DestroyNode(pNode7);
}
// 没有公共结点
// 1 - 2 - 3 - 4
//
// 5 - 6 - 7
void Test2()
{
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, pNode4);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
Test("Test2", pNode1, pNode5, nullptr);
DestroyList(pNode1);
DestroyList(pNode5);
}
// 公共结点是最后一个结点
// 1 - 2 - 3 - 4 \
// 7
// 5 - 6 /
void Test3()
{
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, pNode4);
ConnectListNodes(pNode4, pNode7);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
Test("Test3", pNode1, pNode5, pNode7);
DestroyNode(pNode1);
DestroyNode(pNode2);
DestroyNode(pNode3);
DestroyNode(pNode4);
DestroyNode(pNode5);
DestroyNode(pNode6);
DestroyNode(pNode7);
}
// 公共结点是第一个结点
// 1 - 2 - 3 - 4 - 5
// 两个链表完全重合
void Test4()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
Test("Test4", pNode1, pNode1, pNode1);
DestroyList(pNode1);
}
// 输入的两个链表有一个空链表
void Test5()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
Test("Test5", nullptr, pNode1, nullptr);
DestroyList(pNode1);
}
// 输入的两个链表有一个空链表
void Test6()
{
Test("Test6", nullptr, nullptr, nullptr);
}
void DestroyNode(ListNode* pNode)
{
delete pNode;
pNode = nullptr;
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
return 0;
}