今天重新看了次快速排序算法思想,大概比较了下erlang和Java的实现原理,发现erlang写起来实在轻松多了。
erlang实现代码:
quick([H|T]) -> quick([X || X <- T , X < H ]) ++ [H] ++ quick([X || X <- T , X >= H ]);
quick([]) -> [].
稍微解释一下,其中这个快速排序实现是基于erlang的列表解析,[X || X <-T , X >= H]由3部分组成,分别是构造器和生成器和过滤器。
1.X是列表解析的构造器,是一个函数表达式。
2.X<-T是列表解析的生成器,表示列表T中每一个元组或者变量
3.X<H是列表解析的过滤器,符合过滤器的条件要求,就会将对应的元组或者变量X放到新的列表里面,重新生成一个新的列表。
但是上面的erlang代码只是针对代码优雅性而言的,真正为性能考虑不能使用列表++列表这种模式,这种是极为低效的操作,只有在列表非常短的时候才适用。
Java的实现代码:
private void quickSort2(int[] targetArr, int start, int end) {
int i = start, j = end;
int key = targetArr[start];
while (i < j) {
while (j > i && targetArr[j] >= key) {
j--;
}
if (i < j) {
targetArr[i] = targetArr[j];
}
while (i < j && targetArr[i] < key) {
i++;
}
if (i < j) {
targetArr[j] = targetArr[i];
}
}
targetArr[i] = key;
if (i - start > 1) {
this.quickSort2(targetArr, start, i - 1);
}
if (end - j > 1) {
this.quickSort2(targetArr, j + 1, end);
}
}
上面Java的这个快速排序的方法,就是每次以数组第一个为Key,将数组内比Key要小的换到数组的左边,大的换到数组的右边,一轮结束之后,将Key填到处于大小相隔的位置,通过递归重复实现上面的比较排序来实现快速排序。