首页 > 其他分享 >快速排序的思路和代码

快速排序的思路和代码

时间:2022-10-09 13:31:54浏览次数:47  
标签:arr 基准值 int 代码 pivot 思路 排序 复杂度


首先 快速排序的时间复杂度是 O(n^2) 

    快速排序的平均时间复杂度是 O(nlogn),最好的时间复杂度是O(nlogn),最坏的时间复杂度是 O(n^2) 。时间复杂度是以最坏的来计算的,所以时间复杂度是 O(n^2) 

    最有趣的是思路,和这个算法是一个典型的递归思想。

 

# # 一起看一下快排的思路

快速排序的思路和代码_快速排序

 

  我来稍微分析一点,其实不管是算法还是程序,其实解决问题的方法论永远都是一个,那就是要知道我们的目的是什么,过程是什么,最后程序退出的条件是什么。

  目的是排序,最终从无序变成有序。

  过程:快速排序就是一个达到目的一条路径,因为除了这个还有很多,比方说冒泡,插排,归并,堆排序,桶排序,等等、

  接下来继续去看一快排的思路:

  其实快速排序就是外绕一个思路来展开的,就是从一个无序的数列中,选取一个中间的数,作为基准值,然后如果是升序排序的话,小于基准值的放在左边,大于基准值的放在右边。可想而知的是,这个过程完了以后,我们仅仅能达到的目的是小与基准值的都到了左边,大于基准值的都在右边。但是不能保证左边小于基准值的并不能是有序的,同样大于基准值的都在右边也不能保证是有序的。 所以接着就是一个递归的操作了。在小于基准值的左边,重复这个过程,在大于基准值的右边同样进行一个相同的过程。最后直到程序退出,就能保证是有序的了。

 最后 我们需要关注的一个点是何时退出,其实可以看到的是,我们把小于基准值的放在一边,小于基准值的一边有这么几个情况,情况一:小于基准值的数量大于三,那么需要继续递归。情况二:小于基准值的数量为2,接下来只需要判断这两个的大小就再判断做不做交换就行了,另外一种情况就是只有一个值或者没有值的情况了。虽然分析出来只有这三种情况,对于编程的容易性,实际上我们使用指针来判断结束。

public class QuickSort {

public static void main(String[] args) {
//int[] arr = {-9,78,0,23,-567,70, -1,900, 4561};

//测试快排的执行速度
// 创建要给80000个的随机的数组
int[] arr = new int[8000000];
for (int i = 0; i < 8000000; i++) {
arr[i] = (int) (Math.random() * 8000000); // 生成一个[0, 8000000) 数
}

System.out.println("排序前");
Date data1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str = simpleDateFormat.format(data1);
System.out.println("排序前的时间是=" + date1Str);

quickSort(arr, 0, arr.length-1);

Date data2 = new Date();
String date2Str = simpleDateFormat.format(data2);
System.out.println("排序前的时间是=" + date2Str);
//System.out.println("arr=" + 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);
}


}
}

 

标签:arr,基准值,int,代码,pivot,思路,排序,复杂度
From: https://blog.51cto.com/u_15812686/5740251

相关文章

  • 求最大公约数伪代码
    求最大公约数伪代码上网查找什么是求两个数的最大公约数的欧几里得算法(辗转相除法),提交算法说明和网上链接欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大......
  • java----冒泡,选择,插入排序
    1.冒泡排序packagelearnday06排序;//动态录入往数组里录入n个数字,并用冒泡排序importjava.util.Arrays;importjava.util.Scanner;publicclassMaopaopaixu{ publ......
  • 利用 spring 的 bean 和策略模式优雅的写出可扩展的代码
     代码的的其中有个设计原则就是:开闭原则。 我们在开发过程中经常会遇到这样的问题:就是往往需要有不同的计算方案,比如促销方案,打折。 这个例子就是通过利用 spring ......
  • 查找数组中元素 伪代码
    任务详情输入一个固定长度的数组,并输入一个要查找的数,给出能不能检索到的伪代码并测试伪代码setfoundtoFALSEwhile(position<6ANDfoundisFALSE)if(numbers......
  • 输入一个固定长度的数组,并输入一个要查找的数,给出能不能检索到的伪代码并测试
    060175295380465590 Length=6            Readinarrayofvalues             Set......
  • java开发框架低代码平台会不会过时?
    其实,框架一词原先是出现下建筑领域的,主要是指在建造房屋前期构建的建筑骨架。后来在编程领域,框架就引申为应用程序的骨架了,在这个基础上,程序员可以随心加入自己想要的元素,......
  • 一、注册流程梳理及代码封装-14
    #编码#coding=utf-8#浏览器驱动包fromseleniumimportwebdriver#时间包importtime#引入随机数生成包importrandom#使用pip库进行图片解析包/取图片......
  • 四种排序
    对于无序数组的排序,方法有许多,这里可以以数组{12,23,8,15,33,24,77,55}先说四种。1.选择排序顾名思义,选择排序流程如下选择一个最小(或最大)的数,然后将其排在最前端(或最后端);固......
  • 如何使用物联网低代码平台进行设备调试?
    AIRIOT物联网低代码平台具有设备调试功能,通过数据调试,可判断设备接入时间否正常。如何使用AIRIOT平台进行设备调试,操作如下:设备调试设备调试用于平台接入资产后,进......
  • 执行@pytest.mark.run(order=3)排序不起作用
    学习pytest的时候修改测试用例执行顺序,发现顺序没有按照我设置的顺序执行,查询发现我的包没有安装pytest-ordering于是我安装pipinstallpytest-ordering,但提示我在其......