連結串列翻轉(每K個結點進行一次逆置)
阿新 • • 發佈:2019-01-23
連結串列翻轉
給出一個連結串列和一個數k,比如連結串列1→2→3→4→5→6
若k=2,翻轉後2→1→4→3→6→5,
若k=3,翻轉後3→2→1→6→5→4,
若k=4,翻轉後4→3→2→1→5→6,
用程式實現Node* RotateList(Node* list, size_t k).
我的思路是把每K個結點的逆置成的連結串列都當成一條新的連結串列,所以共有m=size/k條,然後再用上一條連結串列的尾tail和當前連結串列的頭newlist連線起來。所以要把每條連結串列的尾儲存起來,但是我們知道這是連結串列的逆置,所以還未逆置的部分的頭就是下條連結串列的尾,也就是程式碼中的head。最後再把剩下的連結串列鏈在新連結串列的尾部即可。
//逆置連結串列K pList* RotateList(pList* pplist, size_t k) { assert(*pplist); int m = Size(*pplist) / k; //計算新連結串列的個數 if (m <= 0 && k==1) { return NULL; } pNode cur = *pplist; pNode tail = cur; //儲存當前連結串列的尾結點 pList* Head = pplist; //返回值,儲存整個連結串列的首節點 for (int i = 0; i < m; i++)//迴圈逆置m條連結串列 { pList newlist = NULL; //每k個結點都當作一條新的連結串列 pNode head = cur; //當前連結串列的頭部,即下條連結串列的尾結點 int K = k; while (K > 0) //k個結點的逆置 { pNode tmp = cur; cur = cur->next; tmp->next = newlist; newlist = tmp; K--; } if (i == 0) //第一條逆置的新連結串列要做整個連結串列的頭 { *Head = newlist; } else //上條連結串列的尾和新連結串列連結起來 { tail->next = newlist; tail = head; //更新連結串列的尾 } } while (cur) //將剩餘的不夠k個的結點鏈在已經逆置好連結串列的尾部 { tail->next = cur; tail = tail->next; cur = cur->next; } return Head; }
測試:對一條連結串列進行多次逆置
void TestList() { pList l1 = NULL; PushBack(&l1, 1); PushBack(&l1, 2); PushBack(&l1, 3); PushBack(&l1, 4); PushBack(&l1, 5); PushBack(&l1, 6); PushBack(&l1, 7); PushBack(&l1, 8); PushBack(&l1, 9); PushBack(&l1, 10); Print(l1); cout << endl; pList* ret1 = RotateList(&l1, 1); Print(*ret1); pList* ret2 = RotateList(&l1, 2); Print(*ret2); pList* ret3 = RotateList(&l1, 3); Print(*ret3); pList* ret4 = RotateList(&l1, 6); Print(*ret4); }