合并单个链表的两半

时间:2012-12-21 11:17:58

标签: algorithm sorting pointers data-structures linked-list


在书面测试中,我遇到了一个问题,内容如下:

我们得到一个整数链表,其中前半部分和后半部分都是独立排序的。编写一个函数来合并这两个部分以创建一个单独的排序链表。

约束:不要使用任何额外的空间。

测试用例和输出:
输入列表1:
4-> 5-> 6-> 7-> 1-> 2-> 3;
输出:
1-> 2-> 3-> 4-> 5-> 6-> 7


输入2:
5-> 6-> 7-> 8-> 1-> 2-> 3-> 4;
输出2:
1-> 2-> 3-> 4-> 5-> 6-> 7-> 8 >

我能想到的是使用两个指针:一个用于前半遍历,一个用于后半遍历。使用它们我可以从头到中(使用第一个指针)和从中间到最后(使用第二个指针)。在同时遍历两个部分的同时,我可以比较值并在需要时进行交换。

但是这种解决方案使用两个消耗内存的指针。

可以不使用任何内存吗?

由于这是笔试,我不能要求澄清。
协助表示赞赏。感谢。

1 个答案:

答案 0 :(得分:4)

当他们说“不要使用额外的空间”时,他们并不意味着指针和标量;它们的意思是“数组”和“动态分配的结构”。在您的情况下,内存量是固定的。

合并两个有序列表很简单:首先,将列表切成两半,然后重新排列其元素的next指针,使列表排序。

您需要三个指针 - newHeadhead1head2

  • head1head2初始化为原始列表的head
  • 提前head2,直到您看到排序顺序中断(即head2->next->value小于head2->value时)。将head2->next设置为NULL,将列表剪切在那里;保留原始head2->next - 这是您的新head2

此时,您有两个独立排序的单独链接列表,您可以应用经典合并算法。将newHead设置为head1head2的较小元素,然后循环移动,将当前最后一个元素的next指针设置为较小的{{1} }或head1。点击head2head1->next == NULL后,将另一个列表的头部分配给首先用完元素的列表的head2->next == NULL。您已完成 - next现在指向已排序列表的开头。