版权声明:中华人民共和国持有版权 https://blog.csdn.net/Fly_Fly_Zhang/article/details/84994155
快速排序: 数据量小的时候,使用插入排序;聚焦相同基准元素法
- 固定位置选取排序:数据越有序,复杂度越高
- 随机选取基准排序
- 三分取中法
思想:均匀的分割待排序序列 :选取一个基准par,定义两个指针 low high 一般基准选取low下标的值;如果high下标的值比par大,high–;反之将high的值放到low 下标; low的操作和high 一样 ;当high和low 相遇时,将par放到low角标,此时,左边全是比par小的,右边全是比par 大的;
快速排序:递归实现 ,一趟排序结束后如果基准左右两边的元素数量大于等于2,那么说明左右还没有有序,那么在确定新的low 和high的值 继续调用此方法;
public static int partion(int []array ,int low,int high){ //一趟快速排序;
int tmp=array[low];
while(low<high){
while(low<high&& array[high]>tmp){ //如果high对应的元素大于tmp;
high--;
}
if(low >= high) {
break;
} else {
array[low] = array[high];
}
while(low < high && array[low] <= tmp) {
low++;
}
if(low >= high) {
break;
} else {
array[high] = array[low];
}
}
array[low] = tmp;
return low;
}
/**
* 时间复杂度:O(nlog2n)
* 空间复杂度:O(log2n)
* 稳定性:不稳定
* @param array
* @param low
* @param high
*/
public static void quick(int [] array ,int low,int high ){
int par=partion(array,low,high); 返回下一趟排序的基准;
if(par>low+1){ //新的基准与边界之间的元素大于等于两个就可以确定新的par
quick(array,low,par-1); //log 2 N; 基准左边递归
}
if(par<high-1){
quick(array ,par+1,high); //右边递归。
}
}
public static void quickSort(int array){
quick(array,0,array.length-1);
}
public static void main(String[] args) {
int[] array = new int[10000];//n log2n
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = random.nextInt(10000)+1;
}
System.out.println(System.currentTimeMillis());
quickSort(array);
System.out.println(System.currentTimeMillis());
System.out.println(Arrays.toString(array));
}
快速排序: 非递归解法 :思想和递归解法差不多,只不过左右两边没有序,将新的low和high压入模拟栈中;在调用确定基准并排序的方法;只要栈不为空,那么就需要进行排序
public class TestQuickSort {
//一趟快速排序函数
public static int partion(int[] array,int low,int high) {
int tmp = array[low];
while(low < high) {
while(low < high && array[high] >= tmp) {
high--;
}
if(low >= high) {
break;
} else {
array[low] = array[high];
}
while(low < high && array[low] <= tmp) {
low++;
}
if(low >= high) {
break;
} else {
array[high] = array[low];
}
}
array[low] = tmp;
return low;
}
public static void quickSort(int [] array){
int high=array.length-1;
int low=0;
int par=partion(array,low,high);
int size=(int)(Math.log(double)array.length/Math.log2d+1); //这里如果闲麻烦可以直接将长度确定为array 的长度;
int [] stack=new int [size*3] //log2n
//按理应该是*2 但是溢出,所以*3 。 可以直接放array的长度;
int top=0;
if(par>low+1){ //先压第一次循环后符合条件的,在进循环
stack[top++]=low; 先入后出
stack[top++]=par-1;
}
if(par<high-1){
stack[top++]=par+1;
stack[top++]=high;
}
while(top>0){ //每次出一对low high 排序
high=stack[--top]; //后进先出
low=stack[--top];
par=partion(array,low,high);//调用一次快排确定新的基准
if(par>low+1){
stack[top++]=low; 先入后出
stack[top++]=par-1;
}
if(par<high-1){
stack[top++]=par+1;
stack[top++]=high;
}
}
}
public static void main(String[] args) {
int[] array = new int[10000];//n log2n
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = random.nextInt(10000)+1;
}
System.out.println(System.currentTimeMillis());
quickSort(array);
System.out.println(System.currentTimeMillis());
System.out.println(Arrays.toString(array));
}
}