链表相关内容
#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 << "\n"; } else { pCur = pHeader; std::cout << pCur->nVal << ","; pCur = pCur->pNext; while(pCur && pCur != pHeader) { std::cout << pCur->nVal << ","; pCur = pCur->pNext; } std::cout << "\n"; } } // 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 << "\n"; 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; }
除特殊说明外,其余所有文章均属原创。未经允许,请勿进行转载或者其他操作
有问题欢迎留言交流