对于数据量比较大的情况,堆排序比较合适,而且堆排序每一轮可以找出当前数据中最大(大顶堆)或最小(小顶堆)的数,所以对于以上问题,用堆排序是不错的选择:比如王者荣耀上亿用户的排名
package ArrayAlgo;
import java.util.Arrays;
//堆排序和获取topK排名、获取leastK排名
public class HeapSort {
public static void main(String[] args) {
int a[] = {51, 46, 20, 18, 65, 97, 82, 30, 77, 50};
//maxHeapSort(a);
// minHeapSort(a);
//System.out.println(Arrays.toString(a));
int[] res = findTopK(a, 3);
//int[] res=findLeastK(a,3);
System.out.println(Arrays.toString(res));
}
//获取topK排名
public static int[] findTopK(int[] array, int k) {
int[] temp = new int[k];
for (int i = 0; i < k; i++) {
temp[i] = array[i];
}
for (int i = k / 2; i >= 0; i--) {
adjustMinHeap(temp, i, k - 1);
}
for (int j = k; j < array.length; j++) {
if (temp[0] < array[j]) { //存在更大的数字
temp[0] = array[j];
adjustMinHeap(temp, 0, k - 1); //重新调整堆
}
}
finalMaxSort(temp);
return temp;
}
//获取leastK排名
public static int[] findLeastK(int[] array, int k) {
int[] temp = new int[k];
for (int i = 0; i < k; i++) {
temp[i] = array[i];
}
for (int i = k / 2; i >= 0; i--) {
adjustMaxHeap(temp, i, k - 1);
}
for (int j = k; j < array.length; j++) {
if (temp[0] > array[j]) { //存在更小的数字
temp[0] = array[j];
adjustMaxHeap(temp, 0, k - 1); //重新调整堆
}
}
finalMinSort(temp);
return temp;
}
//取topK的最后k个数字的排序
public static void finalMaxSort(int[] a) {
int length = a.length;
for (int i = length - 1; i >= 0; i--) {
swap(a, 0, i);
adjustMinHeap(a, 0, i - 1);
}
}
//取leastK的最后k个数字的排序
public static void finalMinSort(int[] a) {
int length = a.length;
for (int i = length - 1; i >= 0; i--) {
swap(a, 0, i);
adjustMaxHeap(a, 0, i - 1);
}
}
//大顶堆排序
public static void maxHeapSort(int[] a) {
int length = a.length;
for (int i = length / 2; i >= 0; i--) {//构建一个大顶堆
adjustMaxHeap(a, i, length - 1);
}
for (int i = length - 1; i >= 0; i--) {
swap(a, 0, i);
adjustMaxHeap(a, 0, i - 1);
}
}
//小顶堆排序
public static void minHeapSort(int[] a) {
int length = a.length;
for (int i = length / 2; i >= 0; i--) {//构建一个小顶堆
adjustMinHeap(a, i, length - 1);
}
for (int i = length - 1; i >= 0; i--) {
swap(a, 0, i);
adjustMinHeap(a, 0, i - 1);
}
}
public static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
//大顶堆调整
public static void adjustMaxHeap(int[] array, int start, int end) {
int temp = array[start];
int child = start*2 + 1;
while (child <= end) {
if (child+1 <= end && array[child + 1] > array[child]) {
child++;
}
if (array[child] < temp) { //如果所有的孩子节点都小于父节点,就结束循环
break;
}else {
array[start] = array[child];
start = child; //迭代
child = child*2 + 1;
}
} //end while
array[start] = temp;
}
//小顶堆调整
public static void adjustMinHeap(int[] a, int start, int end) {
int temp = a[start];
int child = start * 2 + 1;
while (child <= end) {
if (child + 1 <= end && a[child] > a[child + 1]) {
child++;
}
if (a[child] > temp) {
break;
} else {
a[start] = a[child];
start = child;
child = child * 2 + 1;
}
}
a[start] = temp;
}
}