快速排序
说到排序,当然少不了快速排序。快速排序其实是对冒泡排序的一种改进。通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据比另一部分所有数据要小,按照这种方法再对这两部分数据分别进行快速排序,整个排序过程可以递归实现,最后把元素排列成有序。
快速排序的算法非常简单,在待排序的数列中,我们首先找个基准数,为了方便,一般找第一个数作为基准数。接下来我们需要把待排序的数列中小于基准数的元素移动到数列的左边,大的移动到右边,移动结束后,这两个分区的元素就相对有序了。接着再在两个分区中分别进行这种操作,递归下去,知道分区中只有一个数字。这是典型的分治思想,即分治法。
下面,我们来一起实现这个快速排序算法。
public class QuickSort {
private int[] array;
public QuickSort(int[] array) {
this.array = array;
}
public void sort() {
quickSort(array, 0, array.length - 1);
}
/**
* 递归排序
*
* @param src
* @param begin
* @param end
*/
public void quickSort(int[] src, int begin, int end) {
if (begin < end) {
int key = src[begin];
int i = begin;
int j = end;
while (i < j) {
while (i < j && src[j] > key) {
j--;
}
if (i < j) {
src[i] = src[j];
i++;
}
while (i < j && src[i] < key) {
i++;
}
if (i < j) {
src[j] = src[i];
j--;
}
}
src[i] = key;
quickSort(src, begin, i - 1);
quickSort(src, i + 1, end);
}
}
public void print() {
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
public static void testQuickSort() {
int[] array = {5, 9, 1, 6, 5, 8, 4, 3, 2, 19, 15, 7, 0};
QuickSort quickSort = new QuickSort(array);
quickSort.sort();
quickSort.print();
}
快速排序是在冒泡排序的基础上修改来的,冒泡排序每次只能交换相邻两个元素,而快速排序是跳跃式的交换,交换距离很大,因此交换的次数少了很多,速度也快了不少。
快速排序的优化:
1. 三者取中法
由于每次选择的基准值都选择第一位,这就有一个问题,可能会造成每次都需要移动,这样严重影响了算法的性能复杂度趋向于O()。我们当然希望基准值越接近中间值更好,然后我们可以取数列的头、尾、中间数,在三个数中取不大不小的数,就是中间值。这样可以对性能优化。
2. 根据规模大小改变算法
顾名思义,就是改变排序算法,因为在数据量比较小的时候,快速排序没有其他算法性能好,
3. 其他分区方案考虑
有些时候,我们选择的基准数在数列中可能存在多个,这时我们可以改变分区方案,比如可以三区间,大于,小于,等于。
4. 并行处理
由于快速排序是对数组中一部分进行小范围排序,对其他段没有影响,我们当然可以用计算机并行处理,比如多线程,但是,这种方案并不是对算法的优化,只是在运行时的优化。