今天我们来说一说快速排序吧!
其实快速排序跟冒泡排序的原理差不多
快速排序算法流过多次比较和交换来变现挣序,其排序流程如下:
(1)首光设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时左边部分中各元素都小于等于分界值,而右边部分中各元素都大于等于分界值。
(3)然后,上边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分第值,将该部分数据分成左右两部分,同样将左边放置最小值,右边放置最大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分挂好序后,再递归排好右侧部分的顺序。当左、右两部分各数据排序完成后,整个数组的排序也就完成了。
为了更好地理解快速排序算法的执行过程,下面举一个实际数据的例子来一步一步地执行快速排序算法,下面所示。8个整型数据 69、62、89、37、97、17、28、49 是一组无序的数据。对其执行快速排序过程:
(1)首先选取一个分界值,这里选择第一个数据69作为分界值。在变量left中保存数组的最小序号0,在变量right中保存数组的最大序号7,在变量base中保存分界值69;
(2)从数组右侧开始,逐个取出数据与分界值69比较,直到找到比base 小的数据为止,数组最右侧的元素A[right]的值49比base变量中保存的值69小;
(3)将右侧比基准 base小的数(数组元素A[right]中的数)保存到A[left](A[0])元素中。
(4)接下来,从数组左侧开始,逐个取出元素与分界值69比较,直到找到比分界值69大的数据为止。数组最左侧的元素A[left](即 A[0])的值为49,比 base的值小,将left自增1(值为1)。再取 A(left](A[1)的值 62与 base 的值69 比较,62小于69,继续将 left 自增1(值为2),再取A[left](A[2])的值89与base 比较,89大于69,结束查找。
(5)将左侧比分界值69大的数(数组元素A[2])保存到A[right](A[7])元素中。
(6)将分界值69中的值保存到A[left](A[2])中,最后得到的结果如下:
69(left) 62 89 37 97 17 28 49(right) 69(base)
49 62 69 37 97 17 28 89(right) 69(base)
经过这一次分割,base 数据左侧的数(即left 所指向的数据)比分界值69小,而 base数据右侧的数据比base大。
羊的排序。
(7)接下来,通过递归调用,将lef 左侧的数据进行同样的排序,再将 Ieft 右侧的数据进行同样的排序。
经过上述递归调用,最终可完成数据的排序操作。
快速排序算法的代码:
public static void quickSort(int[] arr,int left,int right){
int l=left;//左下标
int r=right;//右下标
//pivot 中轴值
int pivot=arr[(left+right)/2];
int temp=0;//临时变量,交换时使用
//while循环的目的是让比pivot小的值放到左边
//比pivot大的放在右边
while (l<r){
//在pivot左边一直找,直到找到大于等于pivot的值,才退出
while (arr[l]<pivot){
l+=1;
}//在pivot右边一直找,直到找到小于等于pivot的值,才退出
while (arr[r]>pivot){
r-=1;
}
//如果l>=r成立,说明pivot的左右的值,已经按照左边小于等于pivot的值,而右边全部是大于等于pivot的值
if(l>=r){
break;
}
//交换
temp=arr[l];
arr[l]=arr[r];
arr[r]=temp;
//如果交换完后,发现arr[l]==pivot值相等 r--,前移
if(arr[l]==pivot){
r-=1;
}
//如果交换完后,发现arr[r]==pivot值相等 l++,后移
if(arr[r]==pivot){
l+=1;
}
}
//如果l==r,必须l++,r--.否则表现为栈溢出
if(l==r){
l+=1;
r-=1;
}
//向左递归
if(left<r){
quickSort(arr,left,r);
}
//向右递归
if(right>l){
quickSort(arr,l,right);
}
}
结果为:
看一看给80000个数据排序的效率如何?
//创建要给800000个数据的数组
int[] arr=new int[800000];
for(int i=0;i<800000;i++){
arr[i]=(int)(Math.random()*8000000);//生成一个[0,8000000)数
}
Date date1=new Date();
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str=simpleDateFormat.format(date1);
System.out.println("排序前的时间:"+date1Str);
quickSort(arr,0,arr.length-1);
Date date2=new Date();
String date2Str=simpleDateFormat.format(date2);
System.out.println("排序后的时间:"+date2Str);
//System.out.println(Arrays.toString(arr));
结果展示:
基本上都不用花时间,一下子就排出来了
=============================================================
完整代码:
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
/**
* @Author DreamYee
* @Create 2019/10/27 14:18
*/
public class QuickSort {
public static void main(String[] args) {
//int[] arr={-9,78,0,23,-567,70,900,4561};
/*
int[] arr={ 69,62,89,37,97,17,28,49};
System.out.println("排序前的数组:"+"\n"+Arrays.toString(arr));
System.out.println("排序后的数组:");
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
*/
//创建要给800000个数据的数组
int[] arr=new int[800000];
for(int i=0;i<800000;i++){
arr[i]=(int)(Math.random()*8000000);//生成一个[0,8000000)数
}
Date date1=new Date();
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str=simpleDateFormat.format(date1);
System.out.println("排序前的时间:"+date1Str);
quickSort(arr,0,arr.length-1);
Date date2=new Date();
String date2Str=simpleDateFormat.format(date2);
System.out.println("排序后的时间:"+date2Str);
//System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr,int left,int right){
int l=left;//左下标
int r=right;//右下标
//pivot 中轴值
int pivot=arr[(left+right)/2];
int temp=0;//临时变量,交换时使用
//while循环的目的是让比pivot小的值放到左边
//比pivot大的放在右边
while (l<r){
//在pivot左边一直找,直到找到大于等于pivot的值,才退出
while (arr[l]<pivot){
l+=1;
}//在pivot右边一直找,直到找到小于等于pivot的值,才退出
while (arr[r]>pivot){
r-=1;
}
//如果l>=r成立,说明pivot的左右的值,已经按照左边小于等于pivot的值,而右边全部是大于等于pivot的值
if(l>=r){
break;
}
//交换
temp=arr[l];
arr[l]=arr[r];
arr[r]=temp;
//如果交换完后,发现arr[l]==pivot值相等 r--,前移
if(arr[l]==pivot){
r-=1;
}
//如果交换完后,发现arr[r]==pivot值相等 l++,后移
if(arr[r]==pivot){
l+=1;
}
}
//如果l==r,必须l++,r--.否则表现为栈溢出
if(l==r){
l+=1;
r-=1;
}
//向左递归
if(left<r){
quickSort(arr,left,r);
}
//向右递归
if(right>l){
quickSort(arr,l,right);
}
}
}
好了,今天就说到这里吧
哈哈哈,天天好心情!^ _ ^