博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面试-堆排序(heapSort)以及最大/小的k个数-java实现
阅读量:4282 次
发布时间:2019-05-27

本文共 3800 字,大约阅读时间需要 12 分钟。

Q:

同学面试腾讯的时候被问到:王者荣耀用户上亿,如何快速的从亿级数据量中找出排名榜首的几位玩家?
A:
对于这种数据量比较大的情况,堆排序比较合适,而且堆排序每一轮可以找出当前数据中最大(大顶堆)或最小(小顶堆)的数,所以对于以上问题,用堆排序是不错的选择。

以找出输入数据中【最小的k个数】为例,java实现如下:

package com.sap.stone;import java.util.*;public class FindLeastK{
public static void main(String[] args) {
int []array = {
1,5,3,9,7,8,6,2,4}; ArrayList
res = findLeastK(array, 3); System.out.println(res.toString()); ArrayList
res2 = findLeastK_priorityQueue(array, 3); System.out.println(res2.toString()); } //思路1:堆排序 public static ArrayList
findLeastK(int [] array,int k) {
ArrayList
res = new ArrayList
(); int [] temp = new int[k]; for (int i = 0; i < k; i++) {
temp[i] = array[i]; } for (int i = k/2; i >= 0; i--) {
adjustHeap(temp, i, k - 1); } for (int j = k; j < array.length; j++) {
if (temp[0] > array[j]) {
//存在更小的数字 temp[0] = array[j]; adjustHeap(temp, 0, k-1); //重新调整堆 } } for (int i = 0; i < k; i++) {
res.add(temp[i]); } return res; } private static void adjustHeap(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 swap(int []array, int i, int j) {
int temp = array[i]; array[i] = array[j]; array[j] = temp; } //思路2:使用priorityQueue public static ArrayList
findLeastK_priorityQueue(int[] input, int k) { ArrayList
result = new ArrayList
(); int length = input.length; if(k > length || k == 0){ return result; } //priorityQueue默认为小根堆 PriorityQueue
maxHeap = new PriorityQueue
(k, new Comparator
() { public int compare(Integer o1, Integer o2) { return o2.compareTo(o1); //本例使用大根堆,逆序 } }); for (int i = 0; i < length; i++) { if (maxHeap.size() != k) { maxHeap.offer(input[i]); } else if (maxHeap.peek() > input[i]) { Integer temp = maxHeap.poll(); temp = null; maxHeap.offer(input[i]); } } for (Integer integer : maxHeap) { result.add(integer); } return result; }}

堆排序实现如下:

package com.sap.stone;import java.util.List;import java.util.ArrayList;import java.util.Arrays;/** * 堆排序:【不稳定】【适合大容量数据】 * 大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] * 小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] * 思路: * 	1.将无序序列构建成堆,升序大顶堆(降序小顶堆) * 	2.将堆顶元素与末尾元素进行交换,使数组末尾元素最大。 * 	3.然后继续调整堆,再将堆顶元素与当前末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。 * @author stone * 最好,最坏,平均时间复杂度都是O(nlogn) */public class HeapSort {
public static void main(String[] args) {
int []array = {
1,5,3,9,7,8,6,2,4}; heapSort(array); System.out.println(Arrays.toString(array)); System.out.println("\"\"");// ""的转义 } public static void heapSort(int[] array) {
int length = array.length; //build heap for (int i = length/2; i >= 0; i--) {
adjustHeap(array, i, length-1); } //exchange, adjust heap for (int i = array.length - 1; i > 0; i--) {
swap(array, 0, i); adjustHeap(array, 0, i-1); } } //调整堆 private static void adjustHeap(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 swap(int []array, int i, int j) {
int temp = array[i]; array[i] = array[j]; array[j] = temp; }}

在此记录一下。

另附我的另一篇关于排序总结的博客,
链接:

转载地址:http://jvdgi.baihongyu.com/

你可能感兴趣的文章
leetcode-14:求字符串数组最长公共前缀
查看>>
Hadoop和Spark的区别
查看>>
词向量—Word2Vec入门及Gensim实践
查看>>
卷积神经网络CNN 中用1*1 卷积过滤器的作用及优势
查看>>
深度学习: 卷积核尺寸size为什么是 奇数
查看>>
机器学习比赛—杀入Kaggle Top 1%
查看>>
数据如何归一化 类型
查看>>
Summarization 文本摘要进展
查看>>
kmeans聚类算法及复杂度
查看>>
四大机器学习降维算法:PCA、LDA、LLE、Laplacian Eigenmaps
查看>>
阿里2015实习生招聘 面试第一轮学习
查看>>
内存分配器 (Memory Allocator)
查看>>
最大堆 最小堆 解决TOPK问题
查看>>
Python中的shape和reshape()
查看>>
keras实现手写体数字识别功能的CNN
查看>>
keras实现网络流量分类功能的BP神经网络
查看>>
wireshark和xplico
查看>>
You are using pip version 10.0.1, however version 18.1 is available.
查看>>
OSI模型(七层)和TCP/IP模型(四层)对应关系
查看>>
TCP/IP模型,各层协议
查看>>