钟表,可以回到起点,却已不是昨天; 日历,撕下一页简单,把我一天很难.
若是美好,叫做精彩;若是槽糕,叫做经历. 缘分万千,顺其自然;以心换心,才能永远!
链表面试题(C版本)
#include <stdio.h>
#include <stdlib.h>
#pragma once
1. 删除链表中等于给定值 val 的所有结点。
示例 :
输入 : 1->2->6->3->4->5->6, val = 6
输出 : 1->2->3->4->5
解题思路
- (1)遍历链表中的所有结点
- (2)如果结点的val不是要删除的val,就把这个结点尾插到新的链表上
解法一
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* result = NULL;
struct ListNode* last = NULL; //记录result的最后一个结点
struct ListNode* node = head;
while (node != NULL){
struct ListNode* next = node->next;
if (node->val != val){
//尾插到result这个链表上
//结果链表为空链表
if (result == NULL){
result = node;
last = node;
}
else{
last->next = node;
//更新下最后一个结点
last = node;
}
}
else{
//删除节点,先不考虑
}
node = next;
}
if (last != NULL){
last->next = NULL;
}
return result;
}
解法二
输入 : 2->2->3->1->2->1->2->NULL, val = 2
输出 : 3->1->1->NULL
typedef struct ListNode Node;
struct ListNode* removeElements(struct ListNode* head, int val){
if (NULL==head){
return NULL;
}
Node* pPre = NULL;
Node* pCur = head;
while (pCur){
if (val == pCur->val){
if (NULL == pPre){
//删除第一个结点
head = pCur->next;
free(pCur);
pCur = head;
}
else{
pPre->next = pCur->next;
free(pCur);
pCur = pPre->next;
//非第一个结点
}
}
else{
pPre = pCur;
pCur = pCur->next;
}
}
return head;
}
2.反转一个单链表。 空间复杂度为o(1)
示例:
输入 : 1->2->3->4->5->Null
输出 : 5->4->3->2->1->Null
解法一:(建立三个指针)
typedef struct ListNode Node;
struct ListNode* reverseList(struct ListNode* head){
Node* pPre = NULL;
Node* pCur = head; //放在链表中第一个位置
Node* pNext = NULL;
while (pCur){
pNext = pCur->next;
pCur->next = pPre; //指向逆置后的前一个
pPre = pCur;
pCur = pNext;
}
return pPre;
}
解法二:(头插思想)
typedef struct ListNode Node;
struct ListNode* reverseList(struct ListNode* head){
Node* pCur = head;
Node* pNewHead = NULL;
while (pCur){
head = pCur->next;
pCur->next = pNewHead; //pNewHead新链表的头结点
pNewHead = pCur;
pCur = head;
}
return pNewHead;
}
3.给定一个带有头结点head的非空单链表,返回链表的中间节点,如果有两个中间节点,则返回第二个中间节点.
//输入 : 1->2->3->4->5->Null 输出 : 3
//输入 : 1->2->3->4->Null 输出 : 3
typedef struct ListNode Node;
ListNode* ListNode* middleNode(struct ListNode* pHead){
ListNode* pFast = head;
ListNode* pSlow = head;
while (pFast && pFast->next){
pFast = pFast->next->next; //一次走两步
pSlow = pSlow->next; //一次走一步
}
return pSlow;
}
4.输入一个链表,输出该链表中倒数第k个结点.
输入 : 1->2->3->4->5->Null k=2
解法一
(快指针先走k步, 然后两个指针同时往后移动, 直到快指针走到链表的末尾;)
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k){
if (NULL == pListHead || 0 == k){
return NULL;
}
ListNode* pFast = pListHead;
ListNode* pSlow = pListHead;
//让快指针先走k步
while (k--){
if (NULL==pFast){
return NULL;
}
pFast = pFast->next;
}
//让两个指针同时向后移动
while (pFast){
pFast = pFast->next;
pSlow = pSlow->next;
}
return pSlow;
}
解法二
(快指针先走k - 1步, 然后两个指针同时往后移动, 直到快指针走到最后一个节点)
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k){
if (NULL == pListHead || 0 == k){
return NULL;
}
ListNode* pFast = pListHead;
ListNode* pSlow = pListHead;
//让快指针先走k步
while (--k){
if (NULL == pFast){
return NULL;
}
pFast = pFast->next;
}
if (NULL==pFast){
return NULL;
}
//让两个指针同时向后移动
while (pFast->next){
pFast = pFast->next;
pSlow = pSlow->next;
}
return pSlow;
}
4.扩展(删除链表中倒数第k个结点.)
输入 : 1->2->3->4->5->Null k=2
//找到链表中的倒数第k个结点.
//pFast--->k步
while (pFast){
pFast = pFast->next;
pSlow = pSlow;
pSlow = pSlow->next;
}
//删除
if (pHead == pSlow){
pHead = pSlow->next;
free(pSlow);
}
else{
pPreSlow->next = pSlow->next;
free(pSlow);
}
5.将两个有序链表合并为一个新的有序链表并返回,新链表是通过拼接给定的两个链表的所有结点组成的.
输入: 2->3->7->9->Null 链表pL1
输出 : 1->2->2->3->4->6->7->8->9->Null 链表pTail
1->2->4->6->8->Null 链表pL2
typedef struct ListNode Node;
struct ListNode* mergeTwoLists(struct ListNode* l1,
struct ListNode* l2){
if (NULL == l1){
return l2;
}
if(NULL == l2){
return l1;
}
Node head;
Node* pTail = &head;
Node* pL1 = l1;
Node* pL2 = l2;
while (pL1 && pL2){
if (pL1->val <= pL2->val){
pTail->next = pL1;
pL1 = pL1->next;
}
else {
pTail->next = pL2;
pL2 = pL2->next;
}
pTail = pTail->next;
}
if (NULL == pL1){
pTail->next = pL2;
}
else{
pTail->next = pL1;
}
return head.next;
}
6.编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点都排在大于或者等于x的结点之前.
typedef struct ListNode ListNode;
ListNode* partition(ListNode* pHead, int x){
if (NULL == pHead){
return NULL;
}
ListNode lessList(0);
ListNode greaterList(0);
ListNode* pTail1 = &lessList;
ListNode* pTail2 = &greaterList;
ListNode* pCur = pHead;
while (pCur){
if (pCur->val < x){
pTail1->next = pCur;
pTail1 = pTail1->next;
}
else{
pTail2->next = pCur;
pTail2 = pTail2->next;
}
pCur = pCur->next;
}
pTail1->next = NULL;
pTail2->next = NULL;
pTail1->next = greaterList.next;
return lessList.next;
}
7.在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点
//不保留,返回链表头指针.
8.链表的回文结构.c++
解法一
bool chkpalindrome(ListNode* A){
if (NULL==A){
return true;
}
int* p = (int*)malloc(sizeof(int)* 900);
//将链表中所有的结点中的值放到辅助空间中
ListNode* pCur = A;
int size = 0;
while (pCur){
p[size++] = pCur->val;
pCur = pCur->next;
}
int begin = 0;
int end = size - 1;
while (begin < end){
if (p[begin] != p[end]){
free(p);
return false;
}
begin++;
end--;
}
free(p);
return true;
}
解法二:(逆置)
ListNode* ReverseList(ListNode* pHead){
ListNode* pNewHead = NULL;
ListNode* pCur = pHead;
while (pCur){
pHead = pCur->next;
pCur->next = NewHead;
pNewHead = pCur;
pCur = pHead;
}
return pNewHead;
}
bool chkpalindrome(ListNode* A){
if (NULL == A){
return true;
}
//找链表中间位置
ListNode* pFast = A;
ListNode* pSlow = A;
ListNode* pSlowPre = NULL;
while (pFast && pFast -> next){
pFast = pFast->next->next;
pSlowPre = pSlow;
pSlow = pSlow->next;
}
pSlowPre->next = NULL;
ListNode* pCur1 = A;
ListNode* pCur2 = ReverseList(pSlow);
while (pCur1 && pCur2){
if (pCur1->val != pCur2->val){
return false;
}
pCur1 = pCur1->next;
pCur2 = pCur2->next;
}
return true;
}
9.输入两个链表,找出他们的第一个公共结点.(链表不带环)
解题思路
- (1)确认链表是否相交
a.找到并检测最后一个节点是否相同;
- (2)求交点
a.确认哪个链表长;
b.让长的的链表向后走差值步;
c.两个指针同时往后移动,直到相遇.
typedef struct ListNode ListNode;
struct ListNode* getIntersectionNode(struct ListNode* headA, struct
ListNode* headB){
if (NULL == headA || NULL == headB){
return NULL;
}
//1.确认两个链表是否为相交
ListNode* pTailA = headA;
ListNode* pTailB = headB;
int sizeA = 1; //统计结点个数
int sizeB = 1;
//找headA链表中的最后一个结点
while (pTailA->next){
sizeA++;
pTailA = pTailA->next;
}
//找headB链表中的最后一个结点
while (pTailB->next){
sizeB++;
pTailB = pTailB->next;
}
if (pTailA!=pTailB){
return NULL;
}
//两个链表已经相交
int gap = sizeA - sizeB;
ListNode* pCurA = headA;
ListNode* pCurB = headB;
if (gap>0){
while (gap--){
pCurA = pCurA->next;
}
}
else{
while (gap++){
pCurB = pCurB->next;
}
}
while (pCurA!=pCurB){
pCurA = pCurA->next;
pCurB = pCurB->next;
}
return pCurA;
}
9. 扩展.输入两个链表,找出他们的第一个公共结点.(链表可能带环)
10. 给定一个链表,判断链表中是否有环.(链表中的最后一个结点的Next域不指向空)
typedef struct ListNode Node;
bool hasCycle(struct ListNode* head){
Node* pFast = head;
Node* pSlow = head;
while (pFast && pFast->next){
pFast = pFast->next->next;
pSlow = pSlow->next;
if (pFast==pSlow){
return true;
}
}
return false;
}
11. 给定一个链表,返回链表开始入环的第一个结点,如果链表无环,则返回Null.
解题思路
- (1)可给定两个指针, 三个结点(头结点, 入口点, 相遇点);
- (2)指针tail1从头部出发, 指针tail2从相遇点出发, 下次相遇点为入口位置;
typedef struct ListNode Node;
struct ListNode* detecCycle(struct ListNode* head){
Node* pSlow = head;
Node* pFast = head;
while (pFast && pFast->next){
pFast = pFast->next->next;
pSlow = pSlow->next;
if (pFast==pSlow){
break;
}
}
if (NULL == pFast || NULL == pFast->next){
return NULL;
}
Node* pH = head;
Node* pM = pFast;
while (pH!=pM){
pH = pH->next;
pM = pM->next;
}
return pM; //return pH;
}
12. 给定一个链表,每个结点包含一个额外增加的随机指针,该指针可以指向链表中任何结点或者空结点,要求返回这个链表的胜负拷贝.(复杂链表的复制)
解题思路
- (1)在原链表每个结点后插入相同的新结点;
- (2)给新插入结点的随机指针域赋值;
- (3)将新插入结点从原链表中拆出来
Node* BuyNode(int data){
Node* pNewNode = (Node*)malloc(sizeof(Node));
if (NULL == pNewNode){
assert(0);
return NULL;
}
pNewNode->val = data;
pNewNode->next = NULL;
pNewNode->random = NULL;
return pNewNode;
}
class solution{
public:
Node* copyRandomList(Node* head){
if (NULL == head){
return NULL;
}
//在原链表中每个结点后插入值相同的新结点
Node* pCur = head;
while (pCur){
Node* pNewNode = BuyNode(pCur->next);
pNewNode->next = pCur->next;
pCur->next = pNewNode;
pCur = pNewNode->next;
}
//给新插入结点的随机指针域赋值
pCur = head;
while (pCur){
pNewNode = pCur->next;
if (pCur->random){
pNewNode->random = pCur->random->next;
}
pCur = pNewNode->next;
}
//将新插入的结点从原链表中拆下来
pCur = head;
Node* pNewNode = pCur -> next;
while (pCur->next){
pNewNode = pCur->next;
pCur -> next = pNewNode -> next;
pCur = pNewNode;
}
return pNewHead;
}
};
链表面试题(C++版本)
#include <iostream>
using namespace std;
#if 0
// 如果想要通过形参改变外部的实参,必须传递实参的地址
// 如果实参是值,比如 int a; 传递a的地址----一级指针
// 如果实参是指针, 比如: int* pa = &a; 传递pa的地址-->二级指针
void Swap(int** left, int** right)
{
//cout << &left << " " << &right << endl;
int* temp = *left;
*left = *right;
*right = temp;
}
int main()
{
int a = 10;
int b = 20;
//Swap(a, b);
//Swap(&a, &b);
int* pa = &a;
int* pb = &b;
//Swap(pa, pb);
Swap(&pa, &pb);
return 0;
}
#endif
// 不带头结点的单链表
struct ListNode
{
ListNode(int data)
: _pNext(nullptr)
, _data(data)
{}
ListNode* _pNext;
int _data;
};
void PushBack(ListNode*& pHead, int data)
{
if (nullptr == pHead)
{
pHead = new ListNode(data);
return;
}
// 找到链表中最后一个节点
ListNode* pCur = pHead;
while (pCur->_pNext)
pCur = pCur->_pNext;
pCur->_pNext = new ListNode(data);
}
void PrintList(ListNode* pHead)
{
ListNode* pCur = pHead;
while (pCur)
{
cout << pCur->_data << "--->";
pCur = pCur->_pNext;
}
cout << "NULL" << endl;
}
/
//
#if 0
// 时间复杂度:O(N) 空间复杂度:O(N)
#include <stack>
void ReverseList(ListNode*& pHead)
{
if (nullptr == pHead)
return;
stack<ListNode*> s;
ListNode* pCur = pHead;
while (pCur)
{
s.push(pCur);
pCur = pCur->_pNext;
}
pHead = s.top();
s.pop();
ListNode* pPre = pHead;
while (!s.empty())
{
pCur = s.top();
pPre->_pNext = pCur;
pPre = pCur;
s.pop();
}
pCur->_pNext = nullptr;
}
#endif
#if 0
void ReverseList(ListNode*& pHead)
{
ListNode* pPre = nullptr;
ListNode* pCur = pHead;
ListNode* pNext = nullptr;
while (pCur)
{
pNext = pCur->_pNext;
pCur->_pNext = pPre;
pPre = pCur;
pCur = pNext;
}
pHead = pPre;
}
#endif
// 采用头插法
void ReverseList(ListNode*& pHead)
{
ListNode* pNewHead = nullptr;
ListNode* pCur = pHead;
while (pCur)
{
// 将pCur从原链表中移除
pHead = pCur->_pNext;
// 将pCur头插到新链表中
pCur->_pNext = pNewHead;
pNewHead = pCur;
// 让pCur取原链表中的下一个节点
pCur = pHead;
}
pHead = pNewHead;
}
ListNode* FindMiddleNode(ListNode* pHead)
{
if (nullptr == pHead)
return nullptr;
ListNode* pSlow = pHead;
ListNode* pFast = pHead;
while (pFast && pFast->_pNext)
{
pFast = pFast->_pNext->_pNext;
pSlow = pSlow->_pNext;
}
return pSlow;
}
#if 0
ListNode* FindLastKNode(ListNode* pHead, size_t K)
{
if (nullptr == pHead || 0 == K)
return nullptr;
ListNode* pFast = pHead;
// 后置--,pFast先走K步
while (K--)
{
// 检测:K大于链表长度的情况
if (nullptr == pFast)
return nullptr;
pFast = pFast->_pNext;
}
ListNode* pSlow = pHead;
while (pFast)
{
pFast = pFast->_pNext;
pSlow = pSlow->_pNext;
}
return pSlow;
}
#endif
ListNode* FindLastKNode(ListNode* pHead, size_t K)
{
if (nullptr == pHead || 0 == K)
return nullptr;
ListNode* pFast = pHead;
// 前置--,pFast先走K-1步
while (--K)
{
// 检测:K大于链表长度的情况
if (nullptr == pFast)
return nullptr;
pFast = pFast->_pNext;
}
if (nullptr == pFast)
return nullptr;
ListNode* pSlow = pHead;
while (pFast->_pNext)
{
pFast = pFast->_pNext;
pSlow = pSlow->_pNext;
}
return pSlow;
}
ListNode* DeleteLastKNode(ListNode*& pHead, size_t K)
{
// 1. 找倒数第K个节点
if (nullptr == pHead || 0 == K)
return nullptr;
ListNode* pFast = pHead;
// 后置--,pFast先走K步
while (K--)
{
// 检测:K大于链表长度的情况
if (nullptr == pFast)
return nullptr;
pFast = pFast->_pNext;
}
ListNode* pSlow = pHead;
ListNode* pPre = nullptr;
while (pFast)
{
pFast = pFast->_pNext;
pPre = pSlow;
pSlow = pSlow->_pNext;
}
// 2. 删除节点
if (pSlow == pHead)
{
pHead = pSlow->_pNext;
}
else
{
pPre->_pNext = pSlow->_pNext;
}
delete pSlow;
}
ListNode* MergeList(ListNode* pHead1, ListNode* pHead2)
{
if (nullptr == pHead1)
return pHead2;
if (nullptr == pHead2)
return pHead1;
// 合并之后新链表的头结点
ListNode NewHead(0);
ListNode* pTail = &NewHead;
ListNode* pCur1 = pHead1;
ListNode* pCur2 = pHead2;
while (pCur1 && pCur2)
{
if (pCur1->_data <= pCur2->_data)
{
pTail->_pNext = pCur1;
pCur1 = pCur1->_pNext;
}
else
{
pTail->_pNext = pCur2;
pCur2 = pCur2->_pNext;
}
pTail = pTail->_pNext;
}
if (nullptr == pCur1)
pTail->_pNext = pCur2;
else
pTail->_pNext = pCur1;
return NewHead._pNext;
}
int GetListSize(ListNode* pHead)
{
int count = 0;
ListNode* pCur = pHead;
while (pCur)
{
count++;
pCur = pCur->_pNext;
}
return count;
}
ListNode* GetCrossNode(ListNode* pHead1, ListNode* pHead2)
{
// 0. 参数检测
if (nullptr == pHead1 || nullptr == pHead2)
return nullptr;
// 1. 检测两个链表是否相交
// 检测两个链表中最后一个节点是否相同
ListNode* pTail1 = pHead1;
while (pTail1->_pNext)
pTail1 = pTail1->_pNext;
ListNode* pTail2 = pHead2;
while (pTail2->_pNext)
pTail2 = pTail2->_pNext;
// 两个链表不想交
if (pTail1 != pTail2)
return nullptr;
// 2. 求交点
int size1 = GetListSize(pHead1);
int size2 = GetListSize(pHead2);
// 先让较长的链表往后移动两个链表差值步
int gap = size1 - size2;
ListNode* pCur1 = pHead1;
ListNode* pCur2 = pHead2;
if (gap > 0)
{
// 让pCur1往后移动gap
while (gap--)
pCur1 = pCur1->_pNext;
}
else
{
while (gap++)
pCur2 = pCur2->_pNext;
}
// 让两个指针同时往后移动
while (pCur1 != pCur2)
{
pCur1 = pCur1->_pNext;
pCur2 = pCur2->_pNext;
}
return pCur1;
}
int main()
{
ListNode* pHead1 = nullptr;
PushBack(pHead1, 2);
PushBack(pHead1, 4);
PushBack(pHead1, 7);
PrintList(pHead1);
ListNode* pHead2 = nullptr;
PushBack(pHead2, 1);
PushBack(pHead2, 3);
PushBack(pHead2, 8);
PushBack(pHead2, 9);
PrintList(pHead2);
ListNode* pHead = MergeList(pHead1, pHead2);
PrintList(pHead);
return 0;
}
#include <iostream>
using namespace std;
#if 0
// 如果想要通过形参改变外部的实参,必须传递实参的地址
// 如果实参是值,比如 int a; 传递a的地址----一级指针
// 如果实参是指针,比如: int* pa = &a; 传递pa的地址-->二级指针
void Swap(int** left, int** right)
{
//cout << &left << " " << &right << endl;
int* temp = *left;
*left = *right;
*right = temp;
}
int main()
{
int a = 10;
int b = 20;
//Swap(a, b);
//Swap(&a, &b);
int* pa = &a;
int* pb = &b;
//Swap(pa, pb);
Swap(&pa, &pb);
return 0;
}
#endif
// 不带头结点的单链表
struct ListNode
{
ListNode(int data)
: _pNext(nullptr)
, _data(data)
{}
ListNode* _pNext;
int _data;
};
*&(在函数体中如果改变饿了pHead的指向, 外部的实参也会发生改变; 如果只是传递指针的话, 外部实参修改了, 指针的指向是不会改变的; C语言中需要传二级指针, C++中只需要传一级指针的引用就可以了)
void PushBack(ListNode*& pHead, int data)
{
if (nullptr == pHead)
{
pHead = new ListNode(data);
return;
}
// 找到链表中最后一个节点
ListNode* pCur = pHead;
while (pCur->_pNext)
pCur = pCur->_pNext;
pCur->_pNext = new ListNode(data);
}
void PrintList(ListNode* pHead)
{
ListNode* pCur = pHead;
while (pCur)
{
cout << pCur->_data << "--->";
pCur = pCur->_pNext;
}
cout << "NULL" << endl;
}
/
//单链表的逆置
#if 0
// 时间复杂度:O(N) 空间复杂度:O(N)
#include <stack>
void ReverseList(ListNode*& pHead)
{
if (nullptr == pHead)
return;
stack<ListNode*> s;
ListNode* pCur = pHead;
while (pCur)
{
s.push(pCur);
pCur = pCur->_pNext;
}
pHead = s.top();
s.pop();
ListNode* pPre = pHead;
while (!s.empty())
{
pCur = s.top();
pPre->_pNext = pCur;
pPre = pCur;
s.pop();
}
pCur->_pNext = nullptr;
}
#endif
#if 0
void ReverseList(ListNode*& pHead)
{
ListNode* pPre = nullptr;
ListNode* pCur = pHead;
ListNode* pNext = nullptr;
while (pCur)
{
pNext = pCur->_pNext;
pCur->_pNext = pPre;
pPre = pCur;
pCur = pNext;
}
pHead = pPre;
}
#endif
// 采用头插法
void ReverseList(ListNode*& pHead)
{
ListNode* pNewHead = nullptr;
ListNode* pCur = pHead;
while (pCur)
{
// 将pCur从原链表中移除
pHead = pCur->_pNext;
// 将pCur头插到新链表中
pCur->_pNext = pNewHead;
pNewHead = pCur;
// 让pCur取原链表中的下一个节点
pCur = pHead;
}
pHead = pNewHead;
}
ListNode* FindMiddleNode(ListNode* pHead)
{
if (nullptr == pHead)
return nullptr;
ListNode* pSlow = pHead;
ListNode* pFast = pHead;
while (pFast && pFast->_pNext)
{
pFast = pFast->_pNext->_pNext;
pSlow = pSlow->_pNext;
}
return pSlow;
}
#if 0
ListNode* FindLastKNode(ListNode* pHead, size_t K)
{
if (nullptr == pHead || 0 == K)
return nullptr;
ListNode* pFast = pHead;
// 后置--,pFast先走K步
while (K--)
{
// 检测:K大于链表长度的情况
if (nullptr == pFast)
return nullptr;
pFast = pFast->_pNext;
}
ListNode* pSlow = pHead;
while (pFast)
{
pFast = pFast->_pNext;
pSlow = pSlow->_pNext;
}
return pSlow;
}
#endif
ListNode* FindLastKNode(ListNode* pHead, size_t K)
{
if (nullptr == pHead || 0 == K)
return nullptr;
ListNode* pFast = pHead;
// 前置--,pFast先走K-1步
while (--K)
{
// 检测:K大于链表长度的情况
if (nullptr == pFast)
return nullptr;
pFast = pFast->_pNext;
}
if (nullptr == pFast)
return nullptr;
ListNode* pSlow = pHead;
while (pFast->_pNext)
{
pFast = pFast->_pNext;
pSlow = pSlow->_pNext;
}
return pSlow;
}
//删除链表中第K个结点
ListNode* DeleteLastKNode(ListNode*& pHead, size_t K)
{
// 1. 找倒数第K个节点
if (nullptr == pHead || 0 == K)
return nullptr;
ListNode* pFast = pHead;
// 后置--,pFast先走K步
while (K--)
{
// 检测:K大于链表长度的情况
if (nullptr == pFast)
return nullptr;
pFast = pFast->_pNext;
}
ListNode* pSlow = pHead;
ListNode* pPre = nullptr;
while (pFast)
{
pFast = pFast->_pNext;
pPre = pSlow;
pSlow = pSlow->_pNext;
}
// 2. 删除节点
if (pSlow == pHead)
{
pHead = pSlow->_pNext;
}
else
{
pPre->_pNext = pSlow->_pNext;
}
delete pSlow;
}
//合并链表
ListNode* MergeList(ListNode* pHead1, ListNode* pHead2)
{
if (nullptr == pHead1)
return pHead2;
if (nullptr == pHead2)
return pHead1;
// 合并之后新链表的头结点
ListNode NewHead(0);
ListNode* pTail = &NewHead;
ListNode* pCur1 = pHead1;
ListNode* pCur2 = pHead2;
while (pCur1 && pCur2)
{
if (pCur1->_data <= pCur2->_data)
{
pTail->_pNext = pCur1;
pCur1 = pCur1->_pNext;
}
else
{
pTail->_pNext = pCur2;
pCur2 = pCur2->_pNext;
}
pTail = pTail->_pNext;
}
if (nullptr == pCur1)
pTail->_pNext = pCur2;
else
pTail->_pNext = pCur1;
return NewHead._pNext;
}
//获取链表的结点个数
int GetListSize(ListNode* pHead)
{
int count = 0;
ListNode* pCur = pHead;
while (pCur)
{
count++;
pCur = pCur->_pNext;
}
return count;
}
//
ListNode* GetCrossNode(ListNode* pHead1, ListNode* pHead2)
{
// 0. 参数检测
if (nullptr == pHead1 || nullptr == pHead2)
return nullptr;
// 1. 检测两个链表是否相交
// 检测两个链表中最后一个节点是否相同
ListNode* pTail1 = pHead1;
while (pTail1->_pNext)
pTail1 = pTail1->_pNext;
ListNode* pTail2 = pHead2;
while (pTail2->_pNext)
pTail2 = pTail2->_pNext;
// 两个链表不想交
if (pTail1 != pTail2)
return nullptr;
// 2. 求交点
int size1 = GetListSize(pHead1);
int size2 = GetListSize(pHead2);
// 先让较长的链表往后移动两个链表差值步
int gap = size1 - size2;
ListNode* pCur1 = pHead1;
ListNode* pCur2 = pHead2;
if (gap > 0)
{
// 让pCur1往后移动gap
while (gap--)
pCur1 = pCur1->_pNext;
}
else
{
while (gap++)
pCur2 = pCur2->_pNext;
}
// 让两个指针同时往后移动
while (pCur1 != pCur2)
{
pCur1 = pCur1->_pNext;
pCur2 = pCur2->_pNext;
}
return pCur1;
}
int main()
{
ListNode* pHead1 = nullptr;
PushBack(pHead1, 2);
PushBack(pHead1, 4);
PushBack(pHead1, 7);
PrintList(pHead1);
ListNode* pHead2 = nullptr;
PushBack(pHead2, 1);
PushBack(pHead2, 3);
PushBack(pHead2, 8);
PushBack(pHead2, 9);
PrintList(pHead2);
ListNode* pHead = MergeList(pHead1, pHead2);
PrintList(pHead);
return 0;
}