快速排序也是分而治之的思想,是所有的内排中最好的一种。


public class FastSort {public static int partition(int[] arr, int left, int right){int i = left, j = right;int pivot = arr[i];while(i < j){while(i < j && pivot <= arr[j]) j--;if(i < j) arr[i++] = arr[j];while(i < j && pivot >= arr[i]) i++;if(i < j) arr[j--] = arr[i];}arr[i] = pivot;return i;}// 递归实现public static void sort(int[] arr, int left, int right){if(left >= right) return;int p = partition(arr, left, right);sort(arr, left, p-1);sort(arr, p+1, right);}
// 非递归实现public static void NonRecruitSort(int[] arr, int left, int right){Stack<Integer> stack = new Stack<>();stack.push(left);stack.push(right);while(!stack.isEmpty()){int high = stack.pop();int low = stack.pop();int part = partition(arr, low, high);if(low < part-1){stack.push(low);stack.push(part-1);}if(part+1 < high){stack.push(part+1);stack.push(high);}}}public static void main(String[] args) {int[] arr = {12,34,11,45,25};NonRecruitSort(arr, 0, arr.length-1);System.out.println(Arrays.toString(arr));}
}

快排的趟数取决于递归的深度,最好的情况下是O(log2n)O(log_2n)O(log2​n),最差的情况下是O(n2)O(n^2)O(n2),平均O(nlog2n)O(nlog_2n)O(nlog2​n),这里注明一下最坏的情况是正序或者倒序,最好的情况是每次都能划分相等的两份,怎么优化这个问题,避免最坏的情况呢?这里斯坦福提出了一种选择pivot的方法:median-of-three.

选取第一个、最后一个以及中间的元素的中位数,如4 5 6 7, 第一个4, 最后一个7, 中间的为5, 这三个数的中位数为5, 所以选择5作为pivot,8 2 5 4 7, 三个元素分别为8 5 7, 中位数为7, 所以选择最后一个元素7作为pivot,其实现如下:

private static int choosePivotMedianOfThree(int[] a, int left, int right) {  int mid = 0;if((right-left+1) % 2 == 0) mid = left + (right-left+1)/2 - 1;else mid = left + (right-left+1)/2;//只需要找出中位数即可,不需要交换//有的版本也可以进行交换if(((a[left]-a[mid]) * (a[left]-a[right])) <= 0) return left;else if (((a[mid]-a[left]) * (a[mid]-a[right])) <= 0) return mid;else return right;
}

然后我们在划分的时候,只需要把 choosePivotMedianOfThree 得到的下标和left进行交换相应下标位置的元素,划分依旧没有变化。类似于这样子:

int pivot_index = choosePivotMedianOfThree(a, left, right);//始终将第一个元素作为pivot, 若不是, 则与之交换
if (pivot_index != left) {swap(a, pivot_index, left);
}
int pivot = a[left];

举一个牛客上快排的例子,这题用堆也是可以做到的,小根堆,但是我们用快排做:

import java.util.*;public class Finder {public int findKth(int[] a, int n, int K) {// write code hereint left = 0, right = n-1;if(right <= left || n == 0) return 0;int p = partition(a, left, right);while(p != n-K){if(p > n-K){right = p-1;p = partition(a, left, right);}if(p < n-K){left = p+1;p = partition(a, left, right);}}return a[p];}public int partition(int[] a, int low, int high){int i = low, j = high;int pivot = a[low];while(i<j){while(j > i && pivot <= a[j]) j--;a[i] = a[j];while(j > i && pivot >= a[i]) i++;a[j] = a[i];}a[i] = pivot;return i;}
}

快速排序 (随机选择pivot)相关推荐

  1. 快速排序(随机主元)、随机数生成和随机选择算法

    快速排序(朴素) #include<bits/stdc++.h> using std::cin; using std::cout; using std::endl; /*实际过程见算法笔记 ...

  2. 随机选择算法时间复杂度分析

    随机选择算法时间复杂度分析 首先提供算法的伪代码: 算法是递归算法 时间复杂度分析思路:计算每一次递归语句所消耗的时间,再求和. 为了分析需要,我们先定义如下的量: 定义状态j:数组长度在[(3/4) ...

  3. php判断数组不重复的元素,php从数组中随机选择若干不重复元素

    php从数组中随机选择若干唯一元素 /* * $array = the array to be filtered * $total = the maximum number of items to r ...

  4. 528. 按权重随机选择

    528. 按权重随机选择

  5. php数组选择随机元素,php 数组随机选择一个元素显示的简单示例

    这篇文章主要为大家详细介绍了php 数组随机选择一个元素显示的简单示例,具有一定的参考价值,可以用来参考一下. 本代码演示了如何从php数组中随机选择一个元素显示,感兴趣的小伙伴,下面一起跟随512笔 ...

  6. EL之RF(随机性的Bagging+DTR):利用随机选择属性的bagging方法解决回归(对多变量的数据集+实数值评分预测)问题

    EL之RF(随机性的Bagging+DTR):利用随机选择属性的bagging方法解决回归(对多变量的数据集+实数值评分预测)问题 目录 输出结果 设计思路 核心代码 输出结果 设计思路 核心代码 f ...

  7. 随机算法python_在python中实现随机选择

    想从一个序列中随机抽取若干元素,或者想生成几个随机数. random 模块有大量的函数用来产生随机数和随机选择元素.比如,要想从一个序列中随机的抽取一个元素,可以使用random.choice() : ...

  8. python随机选择_在python中实现随机选择

    想从一个序列中随机抽取若干元素,或者想生成几个随机数. random 模块有大量的函数用来产生随机数和随机选择元素.比如,要想从一个序列中随机的抽取一个元素,可以使用random.choice() : ...

  9. ITK:从图像区域中随机选择像素而不进行替换

    ITK:从图像区域中随机选择像素而不进行替换 内容提要 输出结果 C++实现代码 内容提要 从图像区域中随机选择像素而不进行替换 输出结果 [1, 2] [1, 1] [0, 2] [2, 2] [2 ...

最新文章

  1. 未来安防人工智能需要攻克的几大技术方向
  2. 统计学中的协方差矩阵(阵列信号基础)
  3. jQuery-点击按钮实现回到顶部的两种方式
  4. 金蝶显示中间服务器忙,金蝶显示云服务器繁忙怎么回事
  5. CTeX详细安装步骤
  6. 遥想当年年纪小,追风逐浪没烦恼
  7. 51芯片4*4列阵按键c语言程序,单片机城中社稷.doc
  8. 第十章触发器的创建与管理
  9. Websocket服务器响应包,服务器websocket c++发送二进制类型包,客户端没有任何事件响应...
  10. 使用git管理自己的代码--简单使用流程
  11. 搜索系统中的纠错问题
  12. 朱石景 201671010457 团队项目评审课程学习总结
  13. winmail邮件服务器的搭建,搭建Winmail邮件系统
  14. 3.2常用的调度算法
  15. 华为STUN类协议需要NAT ALG进行帮助吗
  16. 未能解决并且期待解决的第二个诡异事件----HashMap相关方法
  17. 元气骑士如何获得机器人成就皮肤_元气骑士成就系统攻略 成就获取方法一览...
  18. IPQ8072A 如何通过AT指令跟SDX55交互
  19. Android 解决65536
  20. 赋值运算和赋值表达式

热门文章

  1. Elixir:可能成为下一代Web开发语言
  2. 另类保存微信公众平台历史消息的方法 - 星标消息
  3. inux下只显示文件
  4. Calypso - Android和Evolution下的CalDAV/CardDAV/Web...
  5. 同時啟動多個Tomcat服務器
  6. Elasticsearch 5.x 字段折叠的使用
  7. MessageQueue的使用方法(二)
  8. python服务器环境搭建(2)——安装相关软件
  9. bzoj4195 noi2015 day1 t1
  10. 浅谈Kubernetes Service负载均衡实现机制