c语言 topk算法,scala写算法-用小根堆解决topK

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

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)

//代码亲测无误

}

在实现insert与deleteMin时,由于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;

}

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

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

Java最小堆解决TopK问题

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

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

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

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

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

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

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

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

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

scala写算法-快排

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

最大堆 最小堆 解决TOPK问题

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

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

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

随机推荐

月四 周2 iii

同样发生于今天 今天做的一道题引起了我对的回忆 如果说光鸟鸟和电波女对我来说有什么共同之处, 那应该是体验过程我都很认真吧 我还是很喜欢入间人间的书, 不过那本妹主题的新 ...

C&plus;&plus;类的成员函数使用的一些小总结

From: http://blog.csdn.net/xiayefanxing/article/details/7607506 这一阵做项目代码开发的时候,用到了在一个C++文件中使用另一个类的成员函 ...

TortoiseGit - Win7使用Gitblit搭建Git服务器教程

第一步:下载Java并且安装 第二步:配置Java环境变量环境变量 --> 系统变量1新建:变量名:JAVA_HOME变量值:D:\Program Files (x86)\Java\jdk1.6 ...

linkin大话数据结构--Set

Set 集合 Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败. Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法.也 ...

iOS开发 runtime实现原理以及实际开发中的应用

自己写了一个小例子:有一些相关知识点和博客文章 A: 首先现在控制器里面初始化一个对象,然后调用对象的方法: #import "ViewController.h" #import  ...

Android ble蓝牙使用注意

以下均为自己在Android ble开发项目中遇到的问题 1.尽量不要在BluetoothGattCallback里面的回调函数中执行读写通知操作,最多一个,因为例如在onServicesDiscov ...

Python解决乱码问题

解决python乱码问题 字符串在python的内部采用unicode的编码方式,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode ...

Linux chattr 命令详解

常见命令参数 A:即Atime,告诉系统不要修改对这个文件的最后访问时间. S:即Sync,一旦应用程序对这个文件执行了写操作,使系统立刻把修改的结果写到磁盘. a:即Append Only,系统只允 ...

Ubuntu操作异常汇总

1.使用Ubuntu的apt-get安装软件时出现以下错误: Reading package lists... Done Building dependency tree... Done Packag ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值