• 链表相关内容


    #include <iostream>
    typedef struct node {
        int nVal;
        node* pNext;
        node(int val) : nVal(val), pNext(nullptr) {}
    };
    
    // create
    node* create_link(int nNodeCnt, bool is_cycle=false) {
        if (nNodeCnt < 1) {
            std::cout << "fail to create node, node cnt error";
            return nullptr;
        }
        node* pHeader = new node(0);
        node* pCur = pHeader;
        for (int i=1; i < nNodeCnt; ++i) {
            node* pTmp = new node(i);
            pCur->pNext = pTmp;
            pCur = pCur->pNext;
        }
        if (is_cycle) {
            pCur->pNext = pHeader;
        }
        return pHeader;
    }
    // search
    void search_display(node* pHeader, bool is_cycle=false) {
        node* pCur = pHeader;
        if (!is_cycle) {
            while(pCur) {
                std::cout << pCur->nVal << ",";
                pCur = pCur->pNext;
            }
            std::cout << "
    ";
        } else {
            pCur = pHeader;
            std::cout << pCur->nVal << ",";
            pCur = pCur->pNext;
            while(pCur && pCur != pHeader) {
                std::cout << pCur->nVal << ",";
                pCur = pCur->pNext;
            }
            std::cout << "
    ";
        }
    
    }
    // clear
    void clear_link(node* pHeader, bool is_cycle=false) {
        node* pCur = pHeader;
        if (!is_cycle) {
            while (pCur) {
                node* pTmp = pCur;
                pCur = pCur->pNext;
                delete pTmp;
                pTmp = nullptr;
            }
        } else {
            // del first node
            pCur = pHeader;
            node* pPrev = pCur;
            pCur = pCur->pNext;
            delete pPrev;
            pPrev = nullptr;
    
            // del left nodes
            while (pCur && pCur != pHeader) {
                pPrev = pCur;
                pCur = pCur->pNext;
                delete pPrev;
                pPrev = nullptr;
            }
        }
    
    }
    // reverse whole link
    node* reverse(node* pHeader) {
        if (nullptr == pHeader || nullptr == pHeader->pNext) {
            return pHeader;
        }
        node* pCur = pHeader;
        node* pLeft = nullptr;
        node* pRight = nullptr;
        while (pCur) {
            pRight = pCur->pNext;
            pCur->pNext = pLeft;
            pLeft = pCur;
            pCur = pRight;
        }
        return pLeft;
    }
    // reverse 【M,N】
    node* reverse_M_N(node* pHeader, int M, int N) {
        if (M >= N) {
            return pHeader;
        }
        // cur pos
        node* pCur = pHeader;
        // first part tail
        node* pFirstTail = nullptr;
        node* pSecondTail = nullptr;
        // if start pos is the not first element
        if (M > 0) {
            // M - 1
            for (int i=0; i < M-1; ++i) {
                pCur = pCur->pNext;
            }
            // now pCur is at M-1, first part tail
            pFirstTail = pCur;
            // pCur is at M
            pCur = pCur->pNext;
            // second part tail
            pSecondTail = pCur;
        }
    
        // start to reverse
        node* pLeft = nullptr;
        node* pRight = pCur->pNext;
        int curPos = M;
        while (pCur && curPos <= N) {
            pRight = pCur->pNext;
            pCur->pNext = pLeft;
            pLeft = pCur;
            pCur = pRight;
            ++curPos;
        }
    
        // join three parts
        if (M==0) {
            pHeader->pNext = pCur;
            pHeader = pLeft;
            return pHeader;
        } else {
            pFirstTail->pNext = pLeft;
            pSecondTail->pNext = pCur;
            return pHeader;
        }
    }
    // reverse K groups
    node* reverse_grp(node* pHeader, int nCntPerGrp) {
        // signle reverse
        if (nCntPerGrp == 1) {
            return reverse(pHeader);
        }
        // do not reverse
        if (nCntPerGrp == 0 || nullptr == pHeader) {
            return pHeader;
        }
        node* pCur = pHeader;
        int nTotalCnt = 0;
        // get total nodes cnt
        while (pCur) {
            ++nTotalCnt;
            pCur = pCur->pNext;
        }
        // total groups
        int nGrpsCnt = nTotalCnt / nCntPerGrp;
        // total count < nCntPerGrp, do not reverse
        if (nGrpsCnt == 0) {
            return pHeader;
        }
        // reset pCur
        pCur = pHeader;
        // the prev part tail
        node* pPrevTail = nullptr;
        // the cur part tail, will be assigned to the prev part tail in next while cycle
        node* pCurTail = pCur;
    
        // reverse by groups
        for (int i = 1; i <= nGrpsCnt; ++i) {
            node* pLeft = nullptr;
            node* pRight = nullptr;
            int tmpCnt = 1;
            pCurTail = pCur;
            while (pCur && tmpCnt <= nCntPerGrp) {
                pRight = pCur->pNext;
                pCur->pNext = pLeft;
                pLeft = pCur;
                pCur = pRight;
                ++tmpCnt;
            }
            // join cur part and prev part
            if (i==1) {
                // if this is the first groups, save the header
                pPrevTail = pHeader;
                pHeader = pLeft;
            } else {
                // join the prev tail node and cur header node
                pPrevTail->pNext = pLeft;
                // reset pPrevTail
                pPrevTail = pCurTail;
            }
        }
        // join the left part
        pCurTail->pNext = pCur;
        return pHeader;
    }
    // delete Kst node
    node* del_K_node(node* pHeader, int K) {
        if (K <= 1) {
            node* pTmp = pHeader;
            pHeader = pHeader->pNext;
            delete pTmp;
            pTmp = nullptr;
        }
        node* pCur = pHeader;
        node* pTmp = pCur;
        int pos = 1;
        while (pCur) {
            if (pos == K - 1) {
                node* pTmp = pCur->pNext;
                pCur->pNext = pCur->pNext->pNext;
                delete pTmp;
                pTmp = nullptr;
                break;
            }
            pCur = pCur->pNext;
            ++pos;
        }
        return pHeader;
    }
    // delete K backward node
    node* del_K_back_node(node* pHeader, int K) {
        node* pFast = pHeader;
        node* pSlow = pHeader;
        if (K <= 1) {
            K = 1;
        }
        int nCurCntFast = 1;
        for (; nCurCntFast <= K && pFast->pNext; ++nCurCntFast) {
            pFast = pFast->pNext;
        }
        // K > node cnt
        if (nCurCntFast < K) {
            return pHeader;
        }
        // K == node cnt, del header
        if (nCurCntFast == K) {
            node* pTmp = pHeader;
            pHeader = pHeader->pNext;
            delete pTmp;
            pTmp = nullptr;
            return pHeader;
        }
        // del middle element
        while (pFast->pNext && pSlow) {
            pFast = pFast->pNext;
            pSlow = pSlow->pNext;
        }
        // delete K
        node* pTmp = pSlow->pNext;
        pSlow->pNext = pSlow->pNext->pNext;
        delete pTmp;
        pTmp = nullptr;
    
        return pHeader;
    }
    // del mid node
    node* del_middle_node(node* pHeader) {
        if (nullptr == pHeader->pNext) {
            return pHeader;
        }
    
        node* pFast = pHeader;
        node* pSlow = pHeader;
        node* pPrev = pHeader;
        while (pFast->pNext && pSlow) {
            if (pFast->pNext->pNext) {
                pFast = pFast->pNext->pNext;
                pPrev = pSlow;
                pSlow = pSlow->pNext;
            } else {
                pFast = pFast->pNext;
            }
        }
        if (pSlow == pHeader) {
            pHeader = pSlow->pNext;
        } else {
            pPrev->pNext = pPrev->pNext->pNext;
        }
        delete pSlow;
        pSlow = nullptr;
        return pHeader;
    }
    // josephus
    node* show_jose_hus(node* pHeader, int total) {
        // when pos % 3 == 0 and cur_total > 1, del node
        int cur_total = total;
        int pos = 1;
        node* pCur = pHeader;
        node* pPrev = nullptr;
        while (pCur && cur_total > 1) {
            if (3 == pos) {
                // del cur
                pPrev->pNext = pPrev->pNext->pNext;
                node* pTmp = pCur;
                pPrev = pCur;
                pCur = pCur->pNext;
                std::cout << "del: " << pPrev->nVal << "
    ";
                delete pTmp;
                pTmp = nullptr;
                pos = 1;
                --cur_total;
            } else {
                ++pos;
                pPrev = pCur;
                pCur = pCur->pNext;
            }
    
        }
        std::cout << "left one: " << pCur->nVal;
        return pCur;
    }
    // single link has circle and find first common node
    // 快慢指针 当快慢指针相遇时, 慢指针走路程 * 2 = 快指针路程
    // 当相遇时, 快指针从头出发, 步长修改为与慢指针一致, 当两者再次相遇时即为入口
    node* get_link_first_common_node(node* pHeader, bool &has_cycle) {
        has_cycle = false;
        if (nullptr == pHeader) {
            return pHeader;
        }
        node* fast = pHeader;
        node* slow = pHeader;
        while (fast->pNext && fast->pNext->pNext && slow->pNext) {
            fast = fast->pNext->pNext;
            slow = slow->pNext;
            if (fast == slow) {
                has_cycle = true;
            }
        }
        return pHeader;
    }
    // two links encounter and find first common node
    // 快慢指针, 快指针一次移动2个单位, 慢指针一次移动1个单位。移动的同时, 记录当前移动的节点个数。 M, N。当快指针的next = nullptr 时,
    // 保持不动, 慢指针继续, 如果慢指针->next 在nullptr之前与快指针相等, 证明有重合点
    // M - N能够知道长表与慢表的差值, 两个指针分别指向头部, 长表先移动M-N个单位。 然后两个指针一起移动, 当两个指针相等时, 即为重合点
    // random node copy
    
    // link dispart
    
    int main() {
        std::cout << "Hello, World!" << std::endl;
        node* pHeader = create_link(10, false);
        //// origin link
        search_display(pHeader, false);
        //// reverse
        // pHeader = reverse(pHeader);
        //// reverse M_N
        // pHeader = reverse_M_N(pHeader, 4, 2);
        //// reverse by groups
        // pHeader = reverse_grp(pHeader, 4);
        //// del K node
        // pHeader = del_K_node(pHeader, 4);
        //// del K backward node
        //pHeader = del_K_back_node(pHeader, 6);
        //// del middle node
        // pHeader = del_middle_node(pHeader);
        //search_display(pHeader);
        //// josehus
        // pHeader = show_jose_hus(pHeader, 10);
        //// get single cycle first common node
    
        clear_link(pHeader, false);
        return 0;
    }
    

      

    除特殊说明外,其余所有文章均属原创。未经允许,请勿进行转载或者其他操作 有问题欢迎留言交流
  • 相关阅读:
    mysql的安装、启动和基础配置 —— windows版本
    Navicat安装及简单使用
    期货黄金与现货黄金比较
    android 网络编程--socket tcp/ip udp http之间的关系
    socket、tcp、udp、http 的认识及区别
    Android数据传递的五种方法汇总
    android 应用程序Activity之间数据传递与共享的几种途径
    Android数据存储的五种方法汇总
    Android终端与服务器数据传输解决方案
    转载 解决Android与服务器交互大容量数据问题
  • 原文地址:https://www.cnblogs.com/LiuBingBlogs/p/13819538.html
Copyright © 2020-2023  润新知