删除链表节点,删除链表重复节点

//在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;
}
posted @ 2017-08-27 23:22  sold_out  阅读(620)  评论(0编辑  收藏  举报