• 算法系列:链表


    链表定义:

    1 // 链表结点
    2 struct ListNode
    3 {
    4     int          m_nValue;
    5     ListNode*    m_pNext;
    6 };

    常见问题:

    #include <iostream>
    #include <stack>
    
    
    // 输入数据
    int Read()
    {
        int value;
        std::cin >> value;
        return value;
    }
    
    
    // 创建链表
    ListNode* CreateList(int nLen)
    {
        ListNode* pHead = NULL;
        ListNode* pCurr = NULL;
        ListNode* pNext = NULL;
    
        for (int nIdx = 0; nIdx < nLen; ++nIdx)
        {
            pNext = new ListNode;
            pNext->m_nValue = Read();
            pNext->m_pNext = NULL;
    
            if (NULL == pHead)
            {
                pHead = pNext;
            }
            else
            {
                pCurr->m_pNext = pNext;
            }
    
            pCurr = pNext;
        }
    
        if (NULL == pCurr)
        {
            delete pCurr;
            pCurr = NULL;
        }
    
        if (NULL == pNext)
        {
            delete pNext;
            pNext = NULL;
        }
    
        return pHead;
    }
    
    
    // 计算链表长度
    int GetListLength(ListNode* pHead)
    {
        unsigned int nLength = 0;
    
        ListNode* pNode = pHead;
        while (NULL != pNode)
        {
            ++nLength;
            pNode = pNode->m_pNext;
        }
    
        return nLength;
    }
    
    
    // 向链表的末尾添加一个结点
    // pHead 是一个指向指针的指针,由于要修改头结点,必须采用指向指针的指针
    void AddToTail(ListNode** pHead, int value)
    {
        ListNode* pNew = new ListNode;
        pNew->m_nValue = value;
        pNew->m_pNext = NULL;
    
        if (NULL == *pHead)
        {
            *pHead = pNew;
        }
        else
        {
            ListNode* pNode = *pHead;
    
            while (NULL != pNode->m_pNext)
            {
                pNode = pNode->m_pNext;
            }
    
            pNode->m_pNext = pNew;
        }
    }
    
    
    // 删除头结点
    // pHead 是一个指向指针的指针,由于要修改头结点,必须采用指向指针的指针
    void RemoveHead(ListNode** pHead)
    {
        if (NULL != *pHead)
        {
            if (NULL == (*pHead)->m_pNext)
            {
                pHead = NULL;
            }
            else
            {
                ListNode* pNode = *pHead;
                *pHead = (*pHead)->m_pNext;
            }
        }
    }
    
    
    // 删除指定结点
    // pHead 是一个指向指针的指针,由于要修改头结点,必须采用指向指针的指针
    void RemoveNode(ListNode** pHead, int value)
    {
        if (NULL == pHead || NULL == *pHead)
        {
            return;
        }
    
        ListNode* pToBeDeleted = NULL;
        if (value == (*pHead)->m_nValue)
        {
            pToBeDeleted = *pHead;
            *pHead = (*pHead)->m_pNext;
        }
        else
        {
            ListNode* pNode = *pHead;
    
            while (NULL != pNode->m_pNext && value != pNode->m_pNext->m_nValue)
            {
                pNode = pNode->m_pNext;
            }
    
            if (NULL != pNode->m_pNext && value == pNode->m_pNext->m_nValue)
            {
                pToBeDeleted = pNode->m_pNext;
                pNode->m_pNext = pNode->m_pNext->m_pNext;
            }
        }
    
        if (NULL == pToBeDeleted)
        {
            delete pToBeDeleted;
            pToBeDeleted = NULL;
        }
    }
    
    
    // 在O(1)时间删除链表结点
    void DeleteNode(ListNode** pHead, ListNode* pToBeDeleted)
    {
        if (NULL == pHead || NULL == pToBeDeleted)
        {
            return;
        }
    
        // 要删除的结点不是尾结点
        if (NULL != pToBeDeleted->m_pNext)
        {
            ListNode* pNext = pToBeDeleted->m_pNext;
            pToBeDeleted->m_nValue = pNext->m_nValue;
            pToBeDeleted->m_pNext = pNext->m_pNext;
    
            delete pNext;
            pNext = NULL;
        }
        // 链表只有一个结点
        else if (*pHead == pToBeDeleted)
        {
            delete pToBeDeleted;
            pToBeDeleted = NULL;
            *pHead = NULL;
        }
        // 链表有多个结点,要删除的结点是尾结点
        else
        {
            ListNode* pNode = *pHead;
            while (pNode->m_pNext != pToBeDeleted)
            {
                pNode = pNode->m_pNext;
            }
    
            pNode->m_pNext = NULL;
            delete pToBeDeleted;
            pToBeDeleted = NULL;
        }
    }
    
    
    // 从头到尾打印链表
    void PrintList(ListNode* pHead)
    {
        ListNode* pNode = pHead;
        while (NULL != pNode)
        {
            std::cout << pNode->m_nValue << "	";
            pNode = pNode->m_pNext;
        }
    
        std::cout << std::endl;
    }
    
    
    // 从尾到头打印链表
    // 1、用栈实现
    // 2、递归实现
    void PrintListReversingly_Iteratively(ListNode* pHead)
    {
        std::stack<ListNode*> nodes;
    
        ListNode* pNode = pHead;
        while (NULL != pNode)
        {
            nodes.push(pNode);
            pNode = pNode->m_pNext;
        }
    
        while (!nodes.empty())
        {
            pNode = nodes.top();
            std::cout << pNode->m_nValue << "	";
            nodes.pop();
        }
    
        std::cout << std::endl;
    }
    
    
    void PrintListReversingly_Recursively(ListNode* pHead)
    {
        if (NULL != pHead)
        {
            if (NULL != pHead->m_pNext)
            {
                PrintListReversingly_Recursively(pHead->m_pNext);
            }
        }
    
        std::cout << pHead->m_nValue << "	";
    }
    
    
    // 链表中倒数第 k 个结点
    // 用两个指针
    ListNode* FindKthToTail(ListNode* pHead, unsigned int k)
    {
        if (NULL == pHead || 0 == k)
        {
            return NULL;
        }
    
        ListNode* pAhead = pHead;
        ListNode* pBehind = NULL;
    
        for (int nIdx = 0; nIdx < (int)k - 1; ++nIdx)
        {
            if (NULL != pAhead->m_pNext)
            {
                pAhead = pAhead->m_pNext;
            }
            else
            {
                return NULL;
            }
        }
    
        pBehind = pHead;
        while (NULL != pAhead->m_pNext)
        {
            pAhead = pAhead->m_pNext;
            pBehind = pBehind->m_pNext;
        }
    
        return pBehind;
    }
    
    
    
    // 链表的中间结点
    ListNode* FindMidNode(ListNode* pHead)
    {
        if (NULL == pHead)
        {
            return NULL;
        }
    
        ListNode* pAhead = pHead;
        ListNode* pBehind = pHead;
    
        while (NULL != pAhead->m_pNext && NULL != pAhead->m_pNext->m_pNext)
        {
            pAhead = pAhead->m_pNext->m_pNext;
            pBehind = pBehind->m_pNext;
        }
    
        return pBehind;
    }
    
    
    // 判断单链表是否有环
    bool IsLoop(ListNode* pHead)
    {
        bool bLoop = false;
    
        if (NULL == pHead)
        {
            return bLoop;
        }
    
        ListNode* pAhead = pHead;
        ListNode* pBehind = pHead;
    
        while (NULL != pAhead->m_pNext && NULL != pAhead->m_pNext->m_pNext && pAhead != pBehind)
        {
            pAhead = pAhead->m_pNext->m_pNext;
            pBehind = pBehind->m_pNext;
        }
    
        if (pAhead == pBehind)
        {
            bLoop = true;
        }
    
        return bLoop;
    }
    
    
    // 反转链表
    // 1、迭代实现
    // 2、递归实现
    ListNode* ReverseList(ListNode* pHead)
    {
        ListNode* pReversedHead = NULL;
        ListNode* pNode = pHead;
        ListNode* pPrev = NULL;
    
        while (NULL != pNode)
        {
            ListNode* pNext = pNode->m_pNext;
    
            if (NULL == pNext)
            {
                pReversedHead = pNode;
            }
    
            pNode->m_pNext = pPrev;
    
            pPrev = pNode;
            pNode = pNext;
        }
    
        return pReversedHead;
    }
    
    
    ListNode* ReverseList_Recursively(ListNode* pHead)
    {
        if (NULL == pHead || NULL == pHead->m_pNext)
        {
            return pHead;
        }
        
        ListNode* pNode = pHead;
        ListNode* pReversedHead = ReverseList_Recursively(pNode->m_pNext);
        pNode->m_pNext->m_pNext = pNode;
        pNode->m_pNext = NULL;
    
        return pReversedHead;
    }
    
    
    // 合并两个有序链表
    ListNode* MergeList(ListNode* pHead1, ListNode* pHead2)
    {
        if (NULL == pHead1)
        {
            return pHead2;
        }
        else if (NULL == pHead2)
        {
            return pHead1;
        }
    
        ListNode* pMergeHead = NULL;
        if (pHead1->m_nValue < pHead2->m_nValue)
        {
            pMergeHead = pHead1;
            pMergeHead->m_pNext = MergeList(pHead1->m_pNext, pHead2);
        }
        else
        {
            pMergeHead = pHead2;
            pMergeHead->m_pNext = MergeList(pHead1, pHead2->m_pNext);
        }
    
        return pMergeHead;
    }
    
    
    // 两个链表的第一个公共结点
    ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2)
    {
        int nLength1 = GetListLength(pHead1);
        int nLength2 = GetListLength(pHead2);
        
        int nLengthDif = nLength1 - nLength2;
        ListNode* pListHeadLong = pHead1;
        ListNode* pListHeadShort = pHead2;
    
        if (nLength1 < nLength2)
        {
            nLengthDif = nLength2 - nLength1;
            pListHeadLong = pHead2;
            pListHeadShort = pHead1;
        }
    
        for (int nIdx = 0; nIdx < nLengthDif; ++nIdx)
        {
            pListHeadLong = pListHeadLong->m_pNext;
        }
    
        while (NULL != pListHeadLong && NULL != pListHeadShort
            && pListHeadLong != pListHeadShort)
        {
            pListHeadLong = pListHeadLong->m_pNext;
            pListHeadShort = pListHeadShort->m_pNext;
        }
    
        // 得到第一个公共结点
        ListNode* pFirstCommonNode = pListHeadLong;
    
        return pFirstCommonNode;
    }
  • 相关阅读:
    转载:quartz详解:quartz由浅入深
    git提交忽略文件或文件夹
    Spring学习笔记(一)
    转载:RabbitMQ常用命令
    linux安装rabbitMQ
    linux安装redis
    springMVC+spring+mybatis多数据源配置
    (二)RabbitMQ使用笔记
    ASP.NET Core 异常处理与日志记录
    ASP.NET Core中间件实现分布式 Session
  • 原文地址:https://www.cnblogs.com/noryes/p/7567520.html
Copyright © 2020-2023  润新知