如果只允许删除元素并将它们放在数组的前面或后面,那么如何对整数数组进行排序?我认为考虑这个问题的一个简单方法是双端队列,但我不确定什么是最有效的算法。
如果我要选择最大的元素,将它放在前面,然后选择第二大元素,将它放在前面,重复...时间复杂度为O(n ^ 2)。有什么更好的解决这个问题的方法?
你不一定需要使用数组,它也可以是一个arrayList(听起来更好,因为插入前面或后面不会涉及移动所有内容。
谢谢!这不是作业,只是好奇!
答案 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)
我不能确定在你的限制下我能做到这一点:
x
是的,它是一个众所周知的名为Quicksort的算法,运行于O(n lg n)
(平均情况)
编辑:修改问题后,我认为实施的数据结构更为重要
对于数据结构,我认为链表就足够了?虽然在链表上使用quicksort并不是一个好主意(你可能想要实现合并排序,复杂性仍然相同),因为常量会变得比数组上的正常快速排序大得多(由于随机访问变为O(n)代替O(1))