【问题标题】:Change the order of nodes in a single-linked list改变单链表中节点的顺序
【发布时间】:2015-06-18 10:50:43
【问题描述】:

假设我们有一个列表 1-2-3-4-5(列表的值可以没有顺序,例如 2-4-5-3-1);
任务是以如下方式重新排序列表节点(不是值): 1-5-2-4-3.
我编写了使用 2 个临时变量和 1 个指针的函数。但问题是我不知道如何将倒数第二个节点中的“下一个”指针设置为“NULL”,而无需在函数中定义第二个临时指针。 有没有更有效的方法来做到这一点?

void Swap(Node* begin)
{
    if (begin->next != NULL || begin->next->next != NULL)
    {
        Node temp1 = *begin; //this variable is used for iteration
        Node* temp2 = begin; //pointer to the target node
        Node prev; //get the adress of last node
        while (temp1.next != NULL)
        {
            prev = temp1;
            temp1 = *temp1.next;
        }
        prev.next->next = temp2->next;
        temp2->next = prev.next;
        Swap(prev.next->next);
    }

}

【问题讨论】:

  • 你到底想做什么? “1-5-2-4-3”这个顺序代表什么模式?
  • 表示节点的顺序。最后一个节点应该在第一个节点之后,第二个节点之后的倒数第二个节点,等等
  • 所以,Swap 是一个递归函数。
  • 获取指定顺序通常和排序一样。要对链表进行排序,您可以使用归并排序。这假设您有某种方法可以确定两个节点是否有序。
  • 但实际上除了从列表的一侧到另一侧之外,没有办法确定它。这正是我所做的。在对 2 个元素进行排序后,函数递归地对较小的列表进行排序。

标签: c algorithm data-structures linked-list


【解决方案1】:

你可以使用这个算法:o(n)时间复杂度

  1. 计算列表中的节点数(n)。

  2. 将最后 n/2 个节点放入堆栈。

  3. 从头开始遍历列表。

  4. 对于每个遍历的元素,从堆栈中弹出该元素并使其成为遍历元素的下一个元素。

  5. 这样做直到堆栈变空。

  6. 请记住将最后一个节点的 next 指针更改为 NULL。

    (如果是奇数,即使堆栈为空,您也必须再遍历一个元素)

【讨论】:

    【解决方案2】:

    所以基本上你想要做的是这样的:

    N0, N1, ..., Nm -> N0, Nm, N1, Nm-1, ..., Nm/2   if m is even
                    -> N0, Nm, N1, Nm-1, ..., N(m-1/2), N(m+1/2) 
    

    您也许可以从i in (m/2 +1)..m(反向)(假设 m 是偶数)中遍历您的列表,删除节点并将其插入到 i+1'th 位置

    或从i in (m/2 +1)..m(假设 m 是偶数)遍历您的列表,删除节点并将其插入到m-i+1'th 位置

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-12
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多