通过在前端或末端插入来排序数组

时间:2014-02-25 13:40:32

标签: arrays algorithm sorting data-structures queue

如果只允许删除元素并将它们放在数组的前面或后面,那么如何对整数数组进行排序?我认为考虑这个问题的一个简单方法是双端队列,但我不确定什么是最有效的算法。

如果我要选择最大的元素,将它放在前面,然后选择第二大元素,将它放在前面,重复...时间复杂度为O(n ^ 2)。有什么更好的解决这个问题的方法?

你不一定需要使用数组,它也可以是一个arrayList(听起来更好,因为插入前面或后面不会涉及移动所有内容。

谢谢!这不是作业,只是好奇!

3 个答案:

答案 0 :(得分:1)

实际上,您只能使用这些操作进行合并排序。

考虑如何对链表进行合并排序。您创建一个作为目标的空链接列表。然后比较源列表中的前两项并按顺序将它们添加到目标列表(即最低的第一项)。对列表中的每对项目继续。

当您完成比较相邻项目后,目标列表现在成为源,您合并项目1,2,3,4,然后合并项目5,6,7,8等。

只需一个链表就可以做同样的事情。如果你知道列表中有多少项(最坏的情况,迭代并计算它们),那么输出列表就是列表中最后一个节点之后的项。因此,您比较前两个项目并按顺序将它们移动到列表的末尾。重复,直到列表排序。

使用数组执行此操作当然会非常昂贵,因为您不断提升自己以便最终腾出空间。但是你可以通过加倍列表的大小来轻松地使用ArrayList(在Java中)或List<T>(在C#中)。您必须跟踪目标索引(第一次迭代为Count,下次迭代为0等),您可能必须将最终项目移动到列表的前面。你完成了(如果你进行了奇数次的迭代)。当然,您必须在返回之前删除所有额外的项目。但它可以做到。

如果您正在使用ArrayList,则复杂性为O(n log n)时间和O(n)额外空间。 O(1)额外的空间,如果您使用链表进行此操作。

答案 1 :(得分:0)

一种方法是多次遍历每个号码。

如果前一个数字小于当前数字并且:

  • 之前的号码被发送到后面,发送到后面。

  • 以前的号码被发送到前面,留在这里

  • 之前的号码仍然存在,请留在这里

如果前一个数字大于当前数字并且:

  • 以前的号码被发送到后面,留在这里

  • 将前一个号码发送到前面,将其发送到前面。

  • 之前的号码仍然存在,发送到前面。

现在,我不确定时间的复杂性......但它绝对是这样做的方式:)...无论如何,思考它很有趣。我没有想过如何确定最终条件,但我确信这很简单。

答案 2 :(得分:0)

我不能确定在你的限制下我能做到这一点:

  1. 随机选择数组中的元素(pivot),比如它的值为x
  2. 扫描所选元素以外的数组,移动所有元素,其值为&lt; = x在数组前面,移动所有元素值&gt; x在数组的末尾
  3. 递归地执行上面的子阵列(1,i-1)和(i + 1,n),其中第i个元素是数据透视
  4. 是的,它是一个众所周知的名为Quicksort的算法,运行于O(n lg n)(平均情况)

    编辑:修改问题后,我认为实施的数据结构更为重要

    对于数据结构,我认为链表就足够了?虽然在链表上使用quicksort并不是一个好主意(你可能想要实现合并排序,复杂性仍然相同),因为常量会变得比数组上的正常快速排序大得多(由于随机访问变为O(n)代替O(1))