[英]twist a doubly linked list
我有一個由雙向鏈表組成的Chain類。 我想扭曲兩個鏈,以便位於偶數位置的每個節點彼此交換。 鏈條從位置1開始。例如,說
this = {1,2,3,4}; //default chain
aChain = {5,6,7,8};
twist(aChain);
現在這將是{1,6,3,8},aChain將是{5,2,7,4}
當前更新:
void Chain::twist(Chain & other){
Node* firstOdd1 = this -> head_;
Node* firstOdd2 = other -> head_;
Node* firstEven1 = firstOdd1 -> next;
Node* firstEven2 = firstOdd2 -> next;
for(int i = 0; i < size(); i++){
firstOdd1 -> next = firstEven2;
firstOdd2 -> next = firstEven1;
firstEven1 -> prev = firstOdd2;
firstEven2 -> prev = firstOdd1;
if(firstEven1 -> next != NULL && firstEven2 -> next != NULL){
//updating my pointers for the next iteration
firstOdd1 = firstEven1 -> next;
firstOdd2 = firstEven2 -> next;
firstEven1 = firstOdd1 -> next;
firstEven2 = firstOdd2 -> next;}
else break;
}
}
如您所見,我聲明了4個指針,以便在分配過程中不會丟失任何節點。 我還想在循環之后(如果交換了最后一個節點)將尾指針分配給兩個列表的最后一個節點。 類中有一個size()函數可返回鏈的大小。
這就是我剛才為迭代步驟編寫的內容。
我將其留為評論,但還是可以作為答案:
該算法很簡單: 交換鏈中每個偶數節點上的值 。
無需開始擔心尾巴之類的問題,只需遵循該模式,直到您不再能做到(即,您用完偶數節點),然后停下來瞧,問題就解決了!
對於提交的案例,您可以清楚地看到它:
{1,2,3,4};
{5,6,7,8};
==========
TWISTER
==========
| | |
v v v
{1,6,3,8};
{5,2,7,4};
另一個例子:
{1,2,3};
{5,6,7,8,9};
==========
TWISTER
==========
| | |
v v v
{1,6,3};
{5,2,7,8,9};
另一個!
{};
{5,6,7,8,9};
==========
TWISTER
==========
| | |
v v v
{};
{5,6,7,8,9};
{1};
{5};
==========
TWISTER
==========
| | |
v v v
{1};
{5};
也許可以為您提供幫助,創建一個函數,該函數在使用給定節點進行調用時會告訴您是否有可能將其移至下一個偶數位置。
bool can_move_to_even(Node* node) const {
if (node != nullptr) {
return node->next != nullptr && node->next->next != nullptr
&& node->next != this->_tail && node->next->next != this->_tail;
}
return false;
}
對於檢查this->_tail
僅供如果你的this->_tail
是不是要考慮的列表的一部分,但如果是,那么你可以安全地刪除這些文件。
現在,您可以做的是,如果傳入一個偶數節點,它將告訴您該節點是否可以到達下一個偶數節點。 一旦此函數對您正在扭曲的任何鏈條都返回false,那就是您知道該停止了。
注意空值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.