扭曲双重链表

时间:2018-02-02 05:31:17

标签: c++ linked-list

我有一个由双向链表组成的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()函数返回链的大小。

这就是我刚才为迭代步骤编写的内容。

1 个答案:

答案 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,那就是你知道是时候停止了。

小心空值。