快速排序
- 快速排序,从数组中随意选择一个数作为中值(pivot),
- 使数组里的数组分为两部分。 比 中值小的部分在 pivot 左边 , 比中值大的部分在pivot 右边
- 左边 和右边的部分重复1和2步骤,直到只剩下一个数。
- 快速排序是冒泡排序的优化化版,比冒泡排序少了很多的比较次数,冒泡排序只能跟相邻的数进行比较,快速排序是left ,right两个,数组左右索引下标寻找不符数的数进行排序,扩大大了比较和交换的范围,不再是只能跟相邻的数进行比较。
- 开始排序采用分治算法,将一个数分成两部分,左边一部分,和右边一部分。每次进行分部分都确定了中值在数字的排序位置,然后左边在进行分两部分,直到只有一个数时,左边就有序了。右边同理。
package 排序;
import java.lang.annotation.Retention;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class QuickSort {
public static void main(String[] args) {
int [] array=new int[80000000];
for (int i = 0; i <array.length ; i++) {
array[i]=(int)(Math.random()*80000000);
}
Date date1=new Date();
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String d=simpleDateFormat.format(date1);
System.out.println(d);
quick(array,0,array.length-1);
Date date2=new Date();
SimpleDateFormat simpleDateFormat2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String d2=simpleDateFormat2.format(date2);
System.out.println(d2);
}
/**
*
* @param arr 要排序的数组
* @param left 数组的最左端索引
* @param right 数组的最右端索引
*/
public static void quick(int[] arr,int left,int right){
// 取数组中的数为中值
int pivot=arr[(left+right)/2];
// 临时变量保存索引用于遍历数组。不然本身left right数值修改
int l=left;
int r=right;
// 交换临时变量
int temp=0;
// 当r>=l 时表示数组已经遍历完毕,中pivot值左右两边都查询完
while(l<r){
// 从左边,寻找比pivot值大的数的索引
/*l<r 保证数组不越界和是否查询完
* arr【l】<pivot 比pivot小 索引++
* */
while( arr[l] <pivot ){
l++;
}
// 循环退出时 arr【l】>=pivot
// 从右边开始寻找比pivot值小的数的索引
while( arr[r]>pivot){
r--;
}
// 循环退出时 arr【l】<=pivot
/*左边找到比 pivot 大的值
* 右边找到比 pivot 小的值
* 最后进行交换
* l<r 才给交换 5 l 4 r
* */
if(l>=r){
return;
}
if(l<r ){
temp=arr[r];
arr[r]=arr[l];
arr[l]=temp;
}
// 如果交换完后arr[l]=pivot r--后移
if(arr[l]==pivot){
r--;
}
// 如果交换完后arr[r]=pivot l++前移
if(arr[r]==pivot){
l++;
}
}
// l和r错开,形成一个区间
if(l==r){
l++;
r--;
}
// 递归调用
if(r>left)
quick(arr,left,r);
if(right>l)
quick(arr,l,right);
}
}