快速选择算法(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)的主要内容,如果未能解决你的问题,请参考以下文章