快速选择算法(Quick Selection)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速选择算法(Quick Selection)相关的知识,希望对你有一定的参考价值。

参考技术A

  因为快速选择算法是基于快速排序算法改进而来,并且两个算法的作者都是Tony Hoare。所以在讲解快速选择算法前先介绍下快速排序算法。

快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用。快速排序采用了分治的策略,该方法基本思想如下:

  CSDN博主elma_tww对快排的过程进行了详细的讲解,在此搬运其例子进行快排过程的示意。
  例如有一需要排序的数组为:23,45,17,11,13,89,72,26,3,17,11,13(从小到大排序)
  选取数组第一个数23为基准数,存入temp变量中,从数组的左右两边界向中间进行遍历,定义两个指针 i 和 j,i 最开始指向数组的第一个元素,j 最开始指向数组的最后一个元素。
  指针 i 从左向右移动,指针 j 从右向左移动。先移动 j 指针(从右忘左移),当 j 指向的数大于基准数时,略过,j 继续往左移动,直到遇到小于等于基准数的数arr[j],将arr[j]填入arr[i]中;再移动 i 指针,当 i 指向的数小于等于基准数时,略过,i 继续往右移动,直到遇到不比基准数小的数arr[i],将arr[i]填入arr[j]中;再移动 i 指针,再移动 j 指针...(轮换移动),直到 i 和 j 指针相遇,此时将temp(基准数)填入arr[i]中即完成算法的第2个步骤。
  接下来分别将基准数左边和右边的数组按照以上方法进行聚合,直到每个子集只有一个元素,即排序完成。
图例

快速选择算法通常用于解决TopK问题,什么是TopK问题呢,就是从数组中选出第K小或第K大的元素。假设我们要寻找TopK大,我们甚至不需要一个排序的数组,只要arr[n-k]左边是小于arr[n-k]的值,arr[n-k]右边是大于arr[n-k]的值,那么arr[n-k]就是我们要寻找的TopK。和快速排序算法一样,算法开始时选定一个基数,并将其分成左右两部分。和快排不同的是,快速选择并不对左右两部分子数组都进行递归,而只对寻找的的目标所在的子数组进行递归。也正因如此,快速选择算法将平均时间复杂度从O(nlogn)降到O(n),而最坏情况下时间复杂度为O(n^2)。

快速选择算法要点在于划分算法和选择需要递归的子数组。下面对划分算法进行图解示例

在数组[3,2,1,5,6,4]中寻找第2大的元素(以第一次划分为例)

上述即使是划分算法的过程。当划分完毕后若基数所在位置大于k,则对基数左边区域进行划分操作,反之则对右边区域进行划分操作,直到基数所在位置等于k。

算法之排序算法 -- 快速排序 Quick sort

快速排序中心思想 -- 分而治之 Divide and Conquer

分:

    将要排序的素数分为两部分, 左边为大于第一个元数的部分, 右边为小于第一个元素的部分。

治:

    将分开数组的每一部分,重新“分”而治之,知道不可分割。

    不可分割的小单元,其实已经排好序。

    每个不可分割的小单元连在一起就成为一个拍好序的数组。


应用场景:

    找出数组中的K大的数,可以用快速排序的进行查找。


public class QuickSort{
public static void main(String []args){ int[] nums = {3,6,7,9,2,0, 6,1,8,5,4}; sort(nums, 0, nums.length-1); for (int num: nums) { System.out.print(num); System.out.print(" "); } } public static int partition(int[] arr, int start, int end) { if (start >= end) return start; int index = start; for (int i = start + 1; i <= end; i ++ ) { if (arr[i] <= arr[start]) { if (index < end) { index++; swap(arr, index, i); } } } swap(arr, index, start ); return index; } public static void swap(int[] arr, int first, int second) { int temp = arr[first]; arr[first] = arr[second]; arr[second] = temp; } public static void sort(int[] arr, int start, int end) { if (end <= start) return; int index = partition(arr, start, end); sort(arr, start, index-1); sort(arr, index+1, end); } }


以上是关于快速选择算法(Quick Selection)的主要内容,如果未能解决你的问题,请参考以下文章

交换排序—快速排序(Quick Sort)

排序算法选择排序(Selection sort)

选择排序(Selection Sort)

排序算法-选择排序(Selection Sort)

python 学习笔记 -- 数据结构与算法 选择排序 Selection Sort

一种算法,两种实现-选择排序