快速排序算法
工作之前一直不懂快速排序算法,今天看了下快速排序算法,跟大家分享下,如果有不妥之处还请建议。
快速排序是对冒泡排序的一种改进,由C.R.A.Hoare于1962年提出,它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
基本思想:
1.先从数列中取出一个数作为控制字。如数组 [K 1 ,K 2 ,…,K n ],以第一个关键字 K 1 为控制字。
2.分区过程,将比这个控制字大的数全放到它的右边,小于或等于它的数全放到它的左边。如将 [K 1 ,K 2 ,…,K n ] 分成两个子区,使左区所有关键字小于等于 K 1 ,右区所有关键字大于等于 K 1 。
3.再对左右区间重复第二步,直到各区间只有一个数
Java 代码如下,直接调用 quickSort(int[] array)函数, 将要排序的数组传入函数中, 在函数中会打印出排序后的结果。
public static void quickSort(int[] array) {
qsort(array, 0, array.length -1);
for (int i= 0; i < array.length; i++ ) {
System.out.println(" the result :" + array[i]);
}
}
//递归方法
public static void qsort(int[] array, int left, int right) {
if (left < right) {
int partition = partition(array, left, right);
qsort(array, 0, partition - 1);
qsort(array, partition +1, right);
}
}
//非递归实现
private static void quickSort(int[] array) {
if (array == null || array.length == 1) {
return;
}
//存放开始于结束索引
Stack<Integer> stack = new Stack<>();
stack.push(0);
stack.push(array.length - 1);
//循环读取栈中的开始结束位置
while (!stack.isEmpty()) {
int right = stack.pop();
int left = stack.pop();
//右边界索引小于左边界索引说明结束了
if (left >= right) {
continue;
}
int i = partition(array, left, right);
if (left < i - 1) {
stack.push(left);
stack.push(i - 1);
}
if (i + 1 < right) {
stack.push(i + 1);
stack.push(right);
}
}
}
public static int partition(int[] array, int left, int right) {
int threshold = array[left];
while (left < right) {
while (left < right && array[right] >= threshold) {
right--;
}
array[left] = array[right];
while (left < right && array[left] <= threshold) {
left++;
}
array[right] = array[left];
}
array[left] = threshold;
return left;
}
递归算法使用的栈由程序自动产生,栈中包含:函数调用时的参数和函数中的局部变量。如果局部变量很多或者函数内部又调用了其他函数,则栈会很大。每次递归调用都要操作很大的栈,效率自然会下降。