我试图以两种方式编写快速排序,一种是就地编码,另一种是使用单独的数组。我有点坚持一些逻辑,看看我有什么,谢谢你的帮助!
public List<Integer> sort(List<Integer> arr){
if(arr.length > 0)
List<Integer> ret = new ArrayList<Integer>();
ret = quickSort(arr);
return ret;
}
public List<Integer> quickSort(List<Integer> arr){
if(arr.length < 2)
return;
int pivot = arr[0];
List<Integer> left = new ArrayList<Integer>();
List<Integer> right = new ArrayList<Integer>();
for(int i = 0; i < arr.length; i++){
if(arr[i] <= pivot)
left.add(arr[i]);
else
right.add(arr[i]);
}
quickSort(left);
quickSort(right);
}
现在我被卡住了,我不知道在递归浏览两套之后我会做什么,大多数情况下我会如何将它们连接在一起并返回一个排序列表。
答案 0 :(得分:1)
您需要将left
和right
序列组合在一起。您需要在算法结束时(在结束}
之前)执行此操作。在伪代码中:
int leftpos = 0, rightpos = 0;
List newlist = new ArrayList();
for(int pos = 0; pos < arr.length; pos++)
if left[pos] < right[pos] newlist.add(left[leftpos++]);
else newlist.add(right[rightpos++]);
return newlist;
这只是一个伪代码。您需要添加代码来检查for循环中每个数组的长度(left
和right
)。
此外,我必须指出,这远非快速排序。如此多的new
数组分配使得算法非常慢,并且在排序时不受欢迎。
此外,第3行的右侧是多余的。您不需要在此处分配任何内容,因为它会在下一行中被覆盖。我只需用这个替换你的第3-5行:
return quickSort(arr);
答案 1 :(得分:0)
让我为你解决这个问题。
首先,除非您使用链接的列表,否则您总是希望进行就地排序(即使这样,它通常需要转换为数组,排序到位,然后转换回来到一个链表 - 它减少了对垃圾收集器的压力。 .NET List&lt;&gt;实际上正在扩展数组。
接下来,快速排序实际上是关于枢轴操作的。这是一种方法:
// Quicksort the sub-array xs[lo..hi].
void QSort(int[] xs, int lo, int hi) {
if (hi <= lo) return; // Don't sort empty or singleton sub-arrays.
var p = [choose some pivot value from xs[lo..hi]];
var a = lo; // Invariant: x[lo..a - 1] <= p.
var z = hi; // Invariant: p < x[z + 1..hi].
while (a <= z) {
if (xs[a] <= p) a++; else Swap(xs, a, z--);
}
QSort(xs, lo, a - 1); // Sort the items <= p.
QSort(xs, z + 1, hi); // Sort the items > p.
}
void Swap(int[] xs, int i, int j) {
var tmp = xs[i];
xs[i] = xs[j];
xs[j] = tmp;
}
答案 2 :(得分:0)
Groovy上的简单实现
def qs(list) {
if (list.size() < 2) return list
def pivot = list[0]
def items = list.groupBy { it <=> pivot }.withDefault { [] }
qs(items[-1]) + items[0] + qs(items[1])
}