目录:

1、引子

2、排序解决法

3、类快排解法

4、最小堆解法

1、引子

日常编码中,常见遇到这样的问题,“寻找最大的数”,此问题非常容易,可暴力直接遍历找出,也可使用分冶策略找出最大值(详见分冶算法)。

本文中需要寻找第k大的数,笔者目前想到3个方法可解决它。

2、排序解决法

如果是一个有序数组,那么寻找第k的大数则相当简单了,且效率为1。数组排序算法中相对较优的算法为快速排序,效率为N*lgN,将数组从到到小排列,第k大的数则为array[k-1]。

快排的思想为,从数组中取任意一个值key,将大于key的值放在key右边,小于key的值放在key左边。key的左边和右边则都是有序的了,然后递归key左边的子数组和key右边的子数组,直到每个子数组长度为1,此时,整个数组均有序了。

代码如下

public static int partition(int[] array, int left, int right) {

int k = array[left];

int i = left;

int j = right;

while (j > i) {

while (array[j] < k && j > i) {

j--;

}

if (j > i) {

array[i] = array[j];

i++;

}

while (array[i] > k && j > i) {

i++;

}

if (j > i) {

array[j] = array[i];

j--;

}

}

array[i] = k;

return i;

}

public static void quickSort(int[] array, int left, int right) {

if (left >= right) {

return;

}

int i = partition(array, left, right);

quickSort(array, left, i - 1);

quickSort(array, i + 1, right);

}

本文中快排略有差异,是按从大到小顺序排列。

快排的partition算法有两种写法,具体可查看快速排序及主定理。此解法效率为N*lgN

3、类快排解法

由于只要求找出第k大的数,没必要将数组中所有值都排序。

快排中的partition算法,返回key在数组中的位置,如果key的位置正好等于k-1,那么问题则得到解决,如果key的位置不等于k-1,可使用递归查找对应子数组。直到key的位置等于k-1,则找对问题的解。

public static int findK(int[] array, int left, int right, int k) {

int i = partition(array, left, right);

if (i == k - 1) {

return array[k - 1];

} else if (i > k - 1) {

return findK(array, left, i - 1, k);

} else if (i < k - 1) {

return findK(array, i + 1, right, k);

}

return 0;

}

此解法的效率值为N*lgK,由于K是常数,所以此解法效率值为N,优于排序解法

4、最小堆解法

最小堆是一种特殊的数组结构,它实质是一个完全二叉树,且树中子节点的值均大于父节点的值,详见 堆排序及优先队列。

考虑到只需要找到第k大的数,构造一个大小为k的最小堆,堆中根节点为最小值。如果数组中最大的几个数均在堆中,那么堆中根节点的值就是问题的解。

构造最小堆

public static void maxHeapify(int[] array, int size, int i) {

int left = 2 * i + 1;

int right = 2 * i + 2;

int small = i;

if (left < size) {

if (array[small] > array[left]) {

small = left;

}

}

if (right < size) {

if (array[small] > array[right]) {

small = right;

}

}

if (small != i) {

int temp = array[small];

array[small] = array[i];

array[i] = temp;

maxHeapify(array, size, small);

}

}

public static void buildHeap(int[] array, int size) {

for (int i = size - 1; i >= 0; i--) {

maxHeapify(array, size, i);

}

}

最小堆已构造完成,将数组中剩余的值与根节点相比,大于根节点的值则将根节点的值与之交换,同时维护最小堆的特性,遍历结束,则根结点即为问题的解。

public static int findKByHeap(int[] array, int k) {

buildHeap(array, k);

for (int i = k + 1; i < array.length; i++) {

if (array[i] > array[0]) {

int temp = array[i];

array[i] = array[0];

array[0] = temp;

maxHeapify(array, k, 0);

}

}

return array[0];

}

java中二叉树中第k大的数,寻找第k大的数相关推荐

  1. 大数据云图:如何在大数据时代寻找下一个大机遇 - 电子书下载(高清版PDF格式+EPUB格式)...

    大数据云图_如何在大数据时代寻找下一个大机遇-大卫•芬雷布 在线阅读                   百度网盘下载(8544) 书名:大数据云图:如何在大数据时代寻找下一个大机遇 作者:大卫•芬雷 ...

  2. 算法-寻找第k小元素(C)

    序言 刚开始我认为,寻找第k小的元素:简单呀,先对所有元素排序,之后再找不就完事啦,这时时间复杂度在O(nlgn).那有没有更好的排序的方法了呢?答案:当然是有的. 算法基本思路: (1) 当规模小于 ...

  3. 《剑指offer》给定一颗二叉搜索树,请找出其中的第k大的结点。

    题目:给定一颗二叉搜索树,请找出其中的第k大的结点.例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4. 解析:看到我写的下面的代码,像一篇文章一样的长, ...

  4. 寻找第k大的元素Java,java – 支持快速第k个最大元素查找的队列数据结构

    我遇到一个需要支持快速第k个最大元素查找的队列数据结构的问题. 此数据结构的要求如下: >队列中的元素不一定是整数,但它们必须彼此可比较,即当我们比较两个元素(它们也可以相等时),我们可以知道哪 ...

  5. 把一个数组的值存入二叉树中,然后利用前序、中序、后序3种方式进行遍历(完整代码以及运行结果)(Java)

    把一个数组的值存入二叉树中,然后利用前序.中序.后序3种方式进行遍历(完整代码以及运行结果) 在最近的面试过程中,听说有小伙伴被面试官要求创建二叉树,然后对该二叉树进行遍历,感觉这一直以来都是一个大家 ...

  6. java 二叉堆_【数据结构】二叉堆:Java实现最大堆及堆排序

    堆在逻辑上一棵完全二叉树,所以可以通过数组进行数据存储,而其余的树大多采用链式结构进行数据存储 堆分类: 大顶堆:大顶堆就是无论在任何一棵(子)树中,父节点都是最大的 小顶堆:小顶堆就是无论在任何一棵 ...

  7. 面试官:海量无序数据,寻找第 K 大的数,越快越好

    最近在参加阿里云举办的<第三届数据库大赛创新上云性能挑战赛--高性能分析型查询引擎赛道>,传送门: https://tianchi.aliyun.com/competition/entra ...

  8. 海量无序数据寻找第 K 大的数

    前言 最近在参加阿里云举办的<第三届数据库大赛创新上云性能挑战赛--高性能分析型查询引擎赛道>,传送门:https://tianchi.aliyun.com/competition/ent ...

  9. 将森林转换为对应的二叉树,若在二叉树中,结点u时结点v的父结点的父结点,则在原来的森林中,u和v可能具有的关系是( )

    将森林转换为对应的二叉树,若在二叉树中,结点u时结点v的父结点的父结点,则在原来的森林中,u和v可能具有的关系是( ① ② ) ① 父子关系 ② 兄弟关系 ③ u的父结点与v的父结点是兄弟关系 森林与 ...

最新文章

  1. 每天一道算法题(24)——自定义幂函数pow
  2. Leangoo看板工具做单团队敏捷开发
  3. Keras K.switch()用法
  4. 解释:什么是云计算?
  5. pycharm如何设置注释的字体颜色
  6. asp ed什么意思 j_这部洗脑ED动画是如何创作出来的?
  7. 镗孔指令g76格式_数控车床螺纹切削指令G32,用途广泛,可分度车削多头螺纹
  8. OpenCV成长之路:直线、轮廓的提取与描述
  9. 第二部分 自动内存管理机制
  10. BZOJ1901 Zju2112 Dynamic Rankings 【树状数组套主席树】
  11. Ubuntu18.04快捷键
  12. R语言 多元方差分析|单因素方差分析
  13. 【Matlab】曲线拟合
  14. WPF编程,使用 Path 画虚线
  15. 【入门】Markdown的高级应用、计算机硬件、linux基本命令
  16. 日语流行口语极短句2
  17. js 点击按钮或者图片,实现图片上传以及将图片显示在页面上
  18. Mac 查找应用安装路径
  19. 安装RapidDesign_v1.3.0.Cracked.DX10.3.Rio
  20. 软件自动化测试方案模板,软件自动化测试ppt模板

热门文章

  1. IT企业工作纯技术性分析(下)
  2. Profinet在制丝线自动化系统中的应用
  3. Arduino实现光控灯
  4. 【深度学习】深度学习三维人体建模最新论文、资源、数据、代码整理分享
  5. lasso特征选择python_[机器学习] 特征选择简明指南
  6. java毕业设计选题推荐 SpringBoot大学生健康档案系统 大学生健康服务平台 高校学生体质检测系统
  7. 知识付费阿里云视频点播功能
  8. android lottie api,Lottie Android 初探
  9. php 雪花算法问题
  10. detectron2系列:config软件包