//在O(1)时间内删除链表节点,给定单向链表的一个头指针和一个节点指针,假设该节点一定是链表中的节点
struct ListNode{
int m_nValue;
ListNode* m_pNext;
};
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted){
//传入特殊值:空链表,空节点指针
if (pListHead == nullptr || *pListHead ==nullptr || pToBeDeleted == nullptr)
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(pToBeDeleted == *pListHead){
*pListHead = nullptr;
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
//链表中有多个节点,删除尾节点,需要顺序遍历链表找到删除节点的前一个节点
else{
ListNode* pNode = *pListHead;
while (pNode->m_pNext != pToBeDeleted){
pNode = pNode->m_pNext;
}
pNode->m_pNext = nullptr;
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
}
//删除链表中的重复节点
void deleteDuplication(ListNode** pListHead){
if(pListHead == nullptr || *pListHead == nullptr)
return;
ListNode* pPreNode = nullptr;
ListNode* pNode = *pListHead;
ListNode* pNext;
while (pNode != nullptr){
pNext = pNode->m_pNext;
bool needDelete = false;
if (pNext != nullptr && pNext->m_nValue == pNode->m_nValue){
needDelete = true;
}
if (!needDelete){
pPreNode = pNode;
pNext = pNode->m_pNext;
}
else{
ListNode* pToBeDel = pNode;
int value = pNode->m_nValue;
while (pToBeDel != nullptr && pToBeDel->m_nValue == value){
pNext = pToBeDel->m_pNext;
delete pToBeDel;
pToBeDel = nullptr;
pToBeDel = pNext;
}
if (pPreNode == nullptr)
*pListHead = pNext;
else
pPreNode->m_pNext = pNext;
pNode = pNext;
}
}
}
//链表中倒数第k个节点:只遍历链表一次的解法
struct ListNode{
int m_nValue;
ListNode* m_pNext;
};
ListNode* findKthToTail(ListNode* pListHead, unsigned int k){
if (pListHead == nullptr || k == 0)
return nullptr;
ListNode* pAhead = pListHead;
ListNode* pBehind = nullptr;
//第一个指针先走k-1步
for (int i = 0; i < k - 1; ++i){
//排除链表中节点个数少于k的情况
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;
}
//求链表中间结点:要求只遍历链表一次,两个指针同时出发,
// 一个指针一次走两步,另一个指针一次走一步,走两步的指针到结尾时候走一步的指针刚好在链表中间
ListNode* middleNodeOfList(ListNode* pListHead){
if (pListhead == nullptr)
return nullptr;
ListNode* pAhead = pListHead;
ListNode* pBehind = pListHead;
while (pAhead->m_pNext != nullptr && pAhead->m_pNext->m_pNext != nullptr){
pAhead = pAhead->m_pNext->m_pNext;
pBehind = pBehind->m_pNext;
}
return pBehind;
}
//链表中环的入口:
//先判断链表是否闭环,返回闭环中一个节点, 不闭环则返回nullptr
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;
else{
pSlow = pSlow->m_pNext;
pFast = pFast->m_pNext;
if (pFast != nullptr)
pFast = pFast->m_pNext;
}
}
return nullptr;
}
//找到环中任意节点,然后计算环中节点个数,再找出环的入口节点
ListNode* entryNodeOfList(ListNode* pHead){
if (pHead == nullptr)
return nullptr;
ListNode* pMeetingNode = meetingNode(pHead);
if (pMeetingNode == nullptr) //非闭环
return nullptr;
//得到环中节点个数
ListNode* pNode1 = pMeetingNode;
int nodesInLoop = 1;
while (pNode1->m_pNext != pMeetingNode){
pNode1 = pNode1->m_pNext;
nodesInLoop++;
}
//pNode1先走 nodesInLoop 步,
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;
}
//反转链表:返回反转后链表的头指针,
ListNode* reverseList(ListNode* pHead){
ListNode* pReversedListHead = nullptr;
ListNode* pPreNode = nullptr;
ListNode* pNode = pHead;
while (pNode != nullptr){
ListNode* pNext = pNode->m_pNext;
if (pNext == nullptr)
pReversedListHead = pNode;
pNode->m_pNext = pPreNode;
pPreNode = pNode;
pNode = pNext;
}
return pReversedListHead;
}
//合并两个排序的链表:(1)递归实现
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* merge(ListNode* pHead1, ListNode* pHead2){
if (pHead1 == nullptr)
return pHead2;
else if (pHead2 == nullptr)
return pHead1;
ListNode* pHead = nullptr;
ListNode* pNode1 = pHead1;
ListNode* pNode2 = pHead2;
ListNode* pPreNode = nullptr;
if (pHead1->m_nValue < pHead2->m_nValue){
pHead = pHead1;
pNode1 = pNode1->m_pNext;
pPreNode = pHead1;
}
else{
pHead = pHead2;
pNode1 = pNode2->m_pNext;
pPreNode = pHead2;
}
while (pNode1 != nullptr && pNode2 != nullptr){
if (pNode1->m_nValue < pNode2->m_nValue){
pPreNode->m_pNext = pNode1;
pPreNode = pNode1;
pNode1 = pNode1->m_pNext;
}
else{
pPreNode->m_pNext = pNode2;
pPreNode = pNode2;
pNode2 = pNode2->m_pNext;
}
}
if (pNode1 != nullptr){
pPreNode->m_pNext = pNode1;
}
if (pNode2 != nullptr){
pPreNode->m_pNext = pNode2;
}
return pHead;
}