快速排序在Top k问题中的运用(quickSort and quickSelect in Top k)
2018-03-10 16:34
786 查看
参考http://blog.csdn.net/shuxingcq/article/details/75041795
快速排序算法在数组中选择一个称为主元(pivot)的元素,将数组分为两部分,使得 第一部分中的所有元素都小于或等于主元,而第二部分的所有元素都大于主元。对第一部分递归地应用快速排序算法,然后对第二部分递归地应用快速排序算法。在最差情况下,划分由 n 个元素构成的数组需要进行 n 次比较和 n 次移动。因此划分所需时间为 O(n) 。最差情况下,每次主元会将数组划分为一个大的子数组和一个空数组。这个大的子数组的规模是在上次划分的子数组的规模减 1 。该算法需要 (n-1)+(n-2)+…+2+1= O(n^2) 时间。
在最佳情况下,每次主元将数组划分为规模大致相等的两部分。设 T(n) 表示使用快速排序算法对包含 n 个元素的数组排序所需的时间,因此,和归并排序的分析相似,快速排序的 T(n)= O(nlogn)。
参考https://www.cnblogs.com/en-heng/p/6336625.html
对于快排在Top k问题中的运用,我们运用Quick Select,Quick Select [1]脱胎于快排(Quick Sort),两个算法的作者都是Hoare,并且思想也非常接近:选取一个基准元素pivot,将数组切分(partition)为两个子数组,比pivot大的扔左子数组,比pivot小的扔右子数组,然后递推地切分子数组。Quick Select不同于Quick Sort的是其没有对每个子数组做切分,而是对目标子数组做切分。其次,Quick Select与Quick Sort一样,是一个不稳定的算法;pivot选取直接影响了算法的好坏,worst case下的时间复杂度达到了O(n2)O(n2)
Quick Select的目标是找出第k大元素,所以
若切分后的左子数组的长度 > k,则第k大元素必出现在左子数组中;
若切分后的左子数组的长度 = k-1,则第k大元素为pivot;
若上述两个条件均不满足,则第k大元素必出现在右子数组中。
下面贴上JAVA代码:import java.util.ArrayList;
public class QuickSort {
//存放最大的k个数
public ArrayList<Integer> result = new ArrayList<Integer>();
public int partition(int[] a,int low,int high){
int privotKey = a[low];
while (low < high){
while (low < high && a[high] >= privotKey){
high --;
}
// swap(a[high],a[low]);
int temp = a[high];
a[high] = a[low];
a[low] = temp;
while (low < high && a[low] <= privotKey ){
low ++;
}
// swap(a[low],a[high]);
temp = a[low];
a[low] = a[high];
a[high] = temp;
}
// for (int b:a) {
// System.out.print(b + " ");
// }
// System.out.println("");
//此时,low = high
// low的位置是基准数的下标
return low;
}
//快排
public void quickSort(int[] a,int low,int high){
if (low < high){
int privotLoc = partition(a,low,high);
quickSort(a,low,privotLoc - 1);
quickSort(a,privotLoc + 1,high);
}
}
//找第k个最大的元素
public int findKthLargest(int[] nums, int k) {
return quickSelect(nums, k, 0, nums.length - 1);
}
// 快速选择找第k个最大的元素
public int quickSelect(int[] arr, int k, int left, int right) {
// if (left == right) return arr[right];
int index = partition(arr, left, right);
if (right - index + 1 > k){
return quickSelect(arr, k, index + 1, right);
}
else if (right - index + 1 == k){
for (int i = index; i <= arr.length - 1; i++) {
result.add(arr[i]);
}
return arr[index];
}
else{
return quickSele
4000
ct(arr, k - right + index - 1, left, index - 1);
}
}
public static void main(String[] args){
int [] a ={47,25,16,24,15,23,1548,255,445,47,54,0,99999,2312213,1223123123,2};
QuickSort quickSort = new QuickSort();
int num = quickSort.findKthLargest(a,3);
// System.out.println(num);
for (Integer i:quickSort.result) {
System.out.println(i);
}
}
}
相关文章推荐
- 快速排序与快速选择算法(quick sort and quick select algorithm)
- 快速选择排序(quickselect)--基于quicksort
- mysql遇见Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre的问题
- 关于Select Where In 的排序问题
- SQL SELECT TOP N equivalent in ORACLE and MySQL
- Mysql解决SELECT list is not in GROUP BY clause and contains nonaggregated column 问题
- 关于Select Where In 的排序问题
- SQL SELECT TOP N equivalent in ORACLE and MySQL
- mysql遇见Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre的问题
- 快速排序Quicksort Array in Java
- 关于Select Where In 的排序问题
- 快速排序 Thinking in QuickSort
- linux上,mysql使用聚合函数group by 时报错:SELECT list is not in GROUP BY clause and contains nonaggre的问题
- SQL SELECT TOP N equivalent in ORACLE and MySQL
- mysql遇见Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre的问题
- Docker安装MySQL遇见Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre的问题
- 关于Select Where In的排序问题
- Docker安装MySQL遇见Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre的问题
- 快速排序 quicksort 细节问题
- SQL SELECT TOP N equivalent in ORACLE and MySQL