topK问题是指从大量数据中获取最大(或最小)的k个数,比如从全校学生中寻找成绩最高的500名学生等等.

本问题可采用小根堆解决.思路是先把源数据中的前k个数放入堆中,然后构建堆,使其保持堆序(可以简单的看成k次insert操作).然后从源数据中的第k个数据之后的每个元素与堆的根节点(小根堆得root是最小的)比较,如果小于root,那么直接pass;如果大于,则执行headp.deleteMin,然后把该元素插入堆中并再次保持堆序.保持堆序需要涉及上滤与下滤的过程.

样例为:

object Main extends App{
val array=Array(0,14,16,19,3,3768,345,3,343,545,455,7567,657,67,65756,756,756,756,7657,657,657,4,534,535,345343,423,4,46546,546,544,546,546,345,345,435,34534,53,5345,45,45,435,43,54,35,435,435,34,5,435,45,65,65,6576,7,65,56,7,45,43,543,53,453,45,345,34)
//数组从1开始
val k=3
val heap=new Heap
1 to k foreach(i=>heap.insert(array(i)))
k+1 to array.length-1 foreach(i=>{
while (heap.getSize>10){
heap.deleteMin
}
if(array(i)>heap.getMin){
heap.deleteMin
heap.insert(array(i))
}
})
heap.print
}

再来说说,Heap是如何实现的

运用scala常常遇到这样的选择:变量的变与不变,这是一个问题.

还有for推导式,实际上是map flatMap等的语法糖.

代码:

class Heap {
type T=Int
private var size=0
val elemnts=new Array[T](200) // 把index=0处的位置空出 2n 2n+1 n/2
def getSize:Int=return size
def insert(x:T):Unit={
def loop(i:Int):Int={
if(elemnts(i/2)<=x)
return i
elemnts(i)=elemnts(i/2)
loop(i/2)
}
val i=loop(size+1)
elemnts(i)=x
size+=1
}
def deleteMin:T={
def loop(i:Int):Int={
if(i>size) return i/2
val left=elemnts(2*i)
val right=elemnts(2*i+1)
if(left<right){
elemnts(i)=left
loop(i*2)
}else{
elemnts(i)=right
loop(2*i+1)
}
}
val result=elemnts(1)
val last=elemnts(size)
val i=loop(1)
elemnts(i)=last
size-=1
return result
}
def print:Unit= 1 to size foreach(i=>println(elemnts(i)))
def getMin:T=return elemnts(1)
//代码亲测无误
}

在实现insertdeleteMin时,由于scala并没有break关键字(虽然你可以使用Breakable这个类实现,实际上通过抛出异常模拟break,不灵活),为实现上虑(insert),考虑用递归来模拟for循环.

代码:

  def insert(x:T):Unit={
def loop(i:Int):Int={
if(elemnts(i/2)<=x)
return i //如果父亲节点比待插入值x小,则本节点应该插入x
elemnts(i)=elemnts(i/2) //上虑
loop(i/2)
}
val i=loop(size+1) //返回待x插入的位置
elemnts(i)=x
size+=1
}

相比从c语言版,基于scala的代码还是容易记忆与相当稳健:

void insert(Element x,Heap* h){
int i=0;
if(isFull(h))
error("full");
for(i=++h->size;h->elements[i/2]>x;i/=2)
h->elements[i]=h->elements[i/2];
h->elements[i]=x;
}

scala写算法-用小根堆解决topK的更多相关文章

  1. 优先队列实现 大小根堆 解决top k 问题

      摘于:http://my.oschina.net/leejun2005/blog/135085 目录:[ - ] 1.认识 PriorityQueue 2.应用:求 Top K 大/小 的元素 3 ...

  2. Java最小堆解决TopK问题

    TopK问题是指从大量数据(源数据)中获取最大(或最小)的K个数据. TopK问题是个很常见的问题:例如学校要从全校学生中找到成绩最高的500名学生,再例如某搜索引擎要统计每天的100条搜索次数最多的 ...

  3. 随手练——HDU Safe Or Unsafe (小根堆解决哈夫曼问题)

    HDU 2527 :http://acm.hdu.edu.cn/showproblem.php?pid=2527 哈夫曼树,学完就忘得差不多了,题目的意思都没看懂,有时间复习下,看了别人的才知道是怎么 ...

  4. 优先队列PriorityQueue实现 大小根堆 解决top k 问题

    转载:https://www.cnblogs.com/lifegoesonitself/p/3391741.html PriorityQueue是从JDK1.5开始提供的新的数据结构接口,它是一种基于 ...

  5. 自己写算法---java的堆的非递归遍历

    import java.io.*; import java.util.*; public class Main { public static void main(String args[]) { S ...

  6. scala写算法-List、Stream、以及剑指Offer里部分题目基于scala解法

    Stream(immutable) Stream是惰性列表.实现细节涉及到lazy懒惰求值.传名参数等等技术(具体细节详见维基百科-求值策略). Stream和List是scala中严格求值和非严格求 ...

  7. scala写算法-快排

    快排算法很经典,今天用scala的函数式思维来整理一下并实现: def qsort(list: List[Int]):List[Int]=list match { case Nil=>Nil c ...

  8. 最大堆 最小堆 解决TOPK问题

    堆:实质是一颗完全二叉树,最大堆的特点:父节点值均大于子节点:最小堆的父节点值均小于子节点: 一般使用连续内存存储堆内的值,因而可以根据当前节点的索引值推断子节点的索引值: 节点i的父节点为(i-1) ...

  9. scala写算法-从后缀表达式构造

    一个例子,比如ab+cde+**,这是一个后缀表达式,那么如何转换为一棵表达式树呢? 先上代码,再解释: object Main extends App{ import Tree.node def i ...

随机推荐

  1. Python网络编程篇之socketserver

    1.socketserver模块和类 socketserver是标准库中的一个高级模块,目标是简化很多样板代码(创建网络客户端和服务器所必须的代码) 这个模块封装了socket编程所需要的各种各样的类 ...

  2. Spring框架——AOP代理

    我们知道AOP代理指的就是设计模式中的代理模式.一种是静态代理,高效,但是代码量偏大:另一种就是动态代理,动态代理又分为SDK下的动态代理,还有CGLIB的动态代理.Spring AOP说是实现了AO ...

  3. SSH批量管理 expect自动交互

    SSH批量管理 expect自动交互 原创博文http://www.cnblogs.com/elvi/p/7662908.html # SSH批量管理 # expect自动交互 ########### ...

  4. 使用Bitbucket Pipeline进行.Net Core项目的自动构建、测试和部署

    1. 引言 首先,Bitbucket提供支持Mercurial和Git版本控制系统的网络托管服务.简单来说,它类似于GitHub,不同之处在于它支持个人免费创建私有项目仓库.除此之外,Bitbucke ...

  5. 如何在HTTP头中隐藏PHP版本号

    PHP 配置默认允许服务器在 HTTP 响应头 X-Powered-By 中显示安装在服务器上的 PHP 版本.出于服务器安全原因(虽然不是主要的要担心的威胁),建议你禁用或隐藏此信息,避免那些针对你 ...

  6. BP算法从原理到python实现

    BP算法从原理到实践 反向传播算法Backpropagation的python实现 觉得有用的话,欢迎一起讨论相互学习~Follow Me 博主接触深度学习已经一段时间,近期在与别人进行讨论时,发现自 ...

  7. UWP 实现App多语言为所欲为切换

    为所欲为,嗯 话不多说,先看效果吧(事先说明,我的方法不是最好的,但是我用着最有效.) [吐槽一下博客园上传的图片,我的App敲鸡漂亮滴,自带亚克力效果,怎么图片上传上来这么多的噪点啊.] [ 商店地 ...

  8. Redis的简单使用和介绍

    1.什么是NoSQL     NoSQL   =   Not Only  SQL     非关系型的数据库      2. 为什么需要NoSQL     High performance  高并发读写 ...

  9. 酷狗歌曲缓存kgtemp转mp3工具

    一直用网易音乐听歌,不过网易的歌曲版权确实是少了一些,在酷狗上可以找到,但收费歌曲只能试听不能下载. 寻找方案 从设置里可以看出,酷狗会设置缓存目录,试听的歌曲存放到这个缓存里. 打开缓存目录: 可以 ...

  10. 【并查集】HDU 1325 Is It A Tree?

    推断是否为树 森林不是树 空树也是树 成环不是树 数据: 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 1 0 0 1 2 2 3 4 5 0 0 2 5 0 0 ans: no ...