二分查找和堆查找
一、二分查找是利用快速排序的二分特点
利用快排在排序时,把数组分成两部分,一部分小于一个值,另一部分大于这个值的特点
将数组用快排从大到小排序,取temp值为数组的第一个数a[start],那么经过一轮调整之后,数组左边的所有值大于或等于temp,数组右边的所有值都小于或等于temp,假设此时temp是数组第i个数。
如果i正好等于K,那么temp就是第K大值
如果i大于K,那么说明第K大值在数组左边,则继续在左边查找
如果i小于K,那么说明第K大值在数组的右边,继续在右边查找
每一轮排序都重复上述步骤,直到找到第K大值。
import java.util.*;
public class Finder {
public int findKth(int[] a, int n, int K) {
return quickSort(a, 0, n - 1, K);
}
private int quickSort(int[] a, int start, int end, int k) {
int temp = a[start];
int s = start, e = end;
while (s < e) {
while (s < e && temp >= a[e]) e --;
a[s] = a[e];
while (s < e && temp <= a[s]) s ++;
a[e] = a[s];
}
a[s] = temp;
if (s == k - 1) {
return a[s];
} else if (s > k - 1) {
return quickSort(a, start, s - 1, k);
} else {
return quickSort(a, s + 1, end, k);
}
}
}二、堆查找是利用堆排序的特点
比较直接,堆排序时,如果是从小到大排序则是先建立一个大顶堆,然后依次从大到小排列各值
第K个排到的值就是第K大值
import java.util.*;
public class Finder {
public int findKth(int[] a, int n, int K) {
// write code here
// build heap
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(a, n, i);
}
// sort top K
for (int i = n - 1; i >= n - K; i--) {
swap(a, 0, i);
heapify(a, i, 0);
}
return a[n-K];
}
private void heapify(int[] a, int n, int k) {
int temp = a[k];
int t = 2 * k + 1;
while (t < n) {
if (t + 1 < n && a[t] < a[t+1]) {
t ++;
}
if (temp < a[t]) {
a[k] = a[t];
k = t;
t = 2 * k + 1;
} else {
break;
}
}
a[k] = temp;
}
private void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}


京公网安备 11010502036488号