【问题标题】:twist a doubly linked list扭曲一个双向链表
【发布时间】:2018-02-02 05:31:17
【问题描述】:

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

这是我刚才为迭代步骤写的。

【问题讨论】:

  • 什么具体问题阻止您实施它?
  • 第一个问题:链表实现有用吗?如果没有,就不能做杰克。制作一个链表类。让链类包含两个链表成员变量。这样,您可以将作业分成两个更易于测试和实施的部分。试图同时做这两件事是一个愚蠢的赌注。
  • 好吧,我有为我设置头、尾、上一个和下一个的构造函数。我相信这些都有效。

标签: c++ linked-list


【解决方案1】:

我将此作为评论留下,但我不妨将其作为答案:

算法很简单:交换链中每个偶数节点的值

无需开始担心尾巴之类的问题,只需遵循该模式,直到您无法再这样做(即您用完偶数节点),然后停下来瞧,问题解决了!

您提交的案例可以清楚地看到:

{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-&gt;_tail 的检查仅适用于您的 this-&gt;_tail 不被视为列表的一部分,但如果是,那么您可以安全地删除它们。

现在你可以做的是,如果你传入一个偶数节点,它会告诉你该节点是否可以到达下一个偶数节点。一旦这个函数为你正在扭曲的任何链条返回 false,那就是你知道是时候停止了。

注意空值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 2014-07-03
    相关资源
    最近更新 更多