我有一个由双向链表组成的Chain类。 我想扭转两个链,使偶数位置的每个节点互相交换。 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()函数返回链的大小。
这就是我刚才为迭代步骤编写的内容。
答案 0 :(得分:2)
我将此作为评论,但我不妨回答:
算法很简单:交换链中每个偶数节点的值。
无需开始担心尾巴和诸如此类的东西,只需遵循该模式,直到你再也不能这样做(即你的节点用完了),然后停下来瞧,问题解决了!
您可以清楚地看到您提交的案例:
{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,那就是你知道是时候停止了。
小心空值。