快速排序
- 递归算法使用的栈由程序自动产生,栈中包含:函数调用时的参数和函数中的局部变量。如果局部变量很多或者函数内部又调用了其他函数,则栈会很大。每次递归调用都要操作很大的栈,效率自然会下降。
- 非递归算法程序员手动利用栈来存储每次分块快排的起始点,栈非空时循环获取中轴入栈。
package sort;
import java.util.Objects;
import java.util.Stack;
/**
* 快速排序的原理:
选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。
一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换。
找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换。
直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值来说,左右两边就是有序的了。
接着分别比较左右两边的序列,重复上述的循环。
*/
public class FastSort{
public static void main(String []args){
int[] a = {12,20,5,16,15,1,30,45,23,9};
int start = 0;
int end = a.length-1;
// sort(a,start,end);
//非递归 栈实现
quickSort(a);
for(int i = 0; i<a.length; i++){
System.out.println(a[i]);
}
}
// public static void sort(int[] a,int low,int high){
// int start = low;
// int end = high;
// //第一个数字key为基准值
// int key = a[low];
//
// while(end>start){
// //从后往前end--,比较a[end]小于key,交换a[end]和key
// while(end>start&&a[end]>=key) //如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
// end--;
// if(a[end]<=key){
// int temp = a[end];
// a[end] = a[start];
// a[start] = temp;
// }
// //从前往后比较
// while(end>start&&a[start]<=key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
// start++;
// if(a[start]>=key){
// int temp = a[start];
// a[start] = a[end];
// a[end] = temp;
// }
// //此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用
// }
// //递归
// if(start>low) sort(a,low,start-1);//左边序列。第一个索引位置到关键值索引-1
// if(end<high) sort(a,end+1,high);//右边序列。从关键值索引+1到最后一个
// }
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;
}
}
转载:https://blog.csdn.net/owenchan1987/article/details/50740479