zoukankan      html  css  js  c++  java
  • 算法系列:链表

    链表定义:

    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;
    }
  • 相关阅读:
    27 Spring Cloud Feign整合Hystrix实现容错处理
    26 Spring Cloud使用Hystrix实现容错处理
    25 Spring Cloud Hystrix缓存与合并请求
    24 Spring Cloud Hystrix资源隔离策略(线程、信号量)
    23 Spring Cloud Hystrix(熔断器)介绍及使用
    22 Spring Cloud Feign的自定义配置及使用
    21 Spring Cloud使用Feign调用服务接口
    20 Spring Cloud Ribbon配置详解
    19 Spring Cloud Ribbon自定义负载均衡策略
    18 Spring Cloud Ribbon负载均衡策略介绍
  • 原文地址:https://www.cnblogs.com/noryes/p/7567520.html
Copyright © 2011-2022 走看看