二分查找和堆查找
一、二分查找是利用快速排序的二分特点
利用快排在排序时,把数组分成两部分,一部分小于一个值,另一部分大于这个值的特点
将数组用快排从大到小排序,取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; } }