持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
本文系作者 不太自律的程序猿原创,转载请私信并在文章开头附带作者和原文地址链接。
快速排序算法
快速排序(Quicksort),是对冒泡排序算法的一种改进。
快速排序算法思路
快速排序算法是一种基于交换的高效的排序算法,它采用了分治法的思想:
1、从数列中取出一个数作为基准数(枢轴,pivot)。
2、将数组进行划分(partition),将比基准数大的元素都移至枢轴右边,将小于等于基准数的元素都移至枢轴左边。
3、再对左右的子区间重复第二步的划分操作,直至每个子区间只有一个元素。
一趟快速排序算法为例
1、设置两个变量i、j,排序开始的时候:i=0,j=arr.length-1;
2、以第一个数组元素作为基准数,赋值给pivot,pivot=arr[0]=arr[i];
3、由后向前搜索j--,找到第一个小于pivot的值arr[j],将arr[j]和arr[i]的值交换;
4、友前向后搜索i++,找到第一个大于pivot的值arr[i],将arr[i]和arr[j]的值交换;
5、重复第3、4步,知道i==j;
假设一开始的数组为:{5,3,7,6,4,1,0,2,9,10,8},选择第一个数作为5基准。
此时i=0,j=10,从后往前找,j--,第一个比5小的数是2,进行交换
{5,3,7,6,4,1,0,2,9,10,8}
得到的数组为:{2,3,7,6,4,1,0,5,9,10,8}
此时i=0,j=7,从前往后找,i++,第一个比5大的数是7,进行交换
{2,3,7,6,4,1,0,5,9,10,8}
得到的数组为:{2,3,5,6,4,1,0,7,9,10,8}
此时i=2,j=7,从后往前找,j--,第一个比5小的数是0,进行交换
{2,3,5,6,4,1,0,7,9,10,8}
得到的数组为:{2,3,0,6,4,1,5,7,9,10,8}
此时i=2,j=6,从前往后找,i++,第一个比5大的数是6,进行交换
{2,3,0,6,4,1,5,7,9,10,8}
得到的数组为:{2,3,0,5,4,1,6,7,9,10,8}
此时i=3,j=6,从后往前找,j--,第一个比5小的数是1,进行交换
{2,3,0,5,4,1,6,7,9,10,8}
得到的数组为:{2,3,0,1,4,5,6,7,9,10,8}
此时i=3,j=5,从前往后找,直到第5位时,i=j=5,key成为了一个分界线,它之前的数都比它小,之后的数都比它大 {2,3,0,1,4,5,6,7,9,10,8}
经过第一趟排序,数组被划分为了两个区,5左边都是小于5的{2,3,0,1,4,},右边的都比5大{6,7,9,10,8},我们再分别对这两个区进行递归操作,直至每个组里面只剩下1个数组,排序完成。
模拟快速排序
public static void quickSort(int[]arr,int left,int right) {
if (left < right) {
int i = left;
int j = right;
while (i < j) {
//从后往前
while (i < j && arr[j] >= arr[i]) {
j--;
}
//交换
swap(arr, i, j);
//从前往后
while (i < j && arr[i] <= arr[j]) {
i++;
}
//交换
swap(arr, i, j);
}
//递归的进行左右两部分的快速排序 (由于此时i和j是相等的,所以下面使用i或者j都可以)
quickSort(arr, left, j - 1);
quickSort(arr, j + 1, right);
}
}
/*
* 调换数组中指定两个位置的数据
*/
private static void swap(int[]arr,int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/*
* 测试
*/
public static void main(String[] args) throws Exception {
int[] arr = {8,1,2,7,6,5,4,3};
System.out.println("排序前:"+Arrays.toString(arr));
quickSort(arr,0,arr.length-1);
System.out.println("排序后:"+Arrays.toString(arr));
}
算法性能分析
时间复杂度
最好情况: 每次数据元素都能平均的分成两个部分。得到一个完全二叉树。如果有n个数据元素,那么数的深度为 时间复杂度为O(nlogn)
最坏情况: 在最坏的情况下,这个数仅有右子树或左子树,比较次数为 (n-1)+(n-2) + (n-3) + … +1=n*(n-1)/2 ,因此时间复杂度为O(n^2),在待排序数据元素已经有序的情况下快速排序时间复杂度最高
空间复杂度为O(n)
快速排序是一种不稳定的排序算法,会改变数据元素的相对位置,也是内排序中平均效率最高的排序算法。
感谢诸君的观看,文中如有纰漏,欢迎在评论区来交流。如果这篇文章帮助到了你,欢迎点赞👍关注。