标签:out highlight save comm std 差值 The random cout
#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;
}
标签:out highlight save comm std 差值 The random cout
原文地址:https://www.cnblogs.com/LiuBingBlogs/p/13819538.html