最小堆前n个数java_java最小堆实现优先权队列和求最大的n个数问题

堆在实现优先权队列和求最大最小的n个数问题上,有着莫大的优势!

对于最大堆和最小堆的定义此处不再赘述。课參考网上文章:http://blog.csdn.net/genios/article/details/8157031

本文主要是对最小堆进行实现和应用,仅供新手參考。

优先权队列

优先权队列是一种很实用的数据结构。操作系统的进程调度就有优先权队列的应用,假设用最小值表示最高的优先权,则使用最小堆。否则使用最大堆。

top-N值为问题:

对于求最大的n个数。能够用最小堆来实现,思路是:将n个数构建成一个最小堆。假设剩下的数有大于堆顶元素的值,则替换掉堆顶元素,再调整为最小堆。直到全部数字遍历完。

贴上源代码:

关键类:

package com.algorithms;

/**

* 最小堆,用数组实现。解决top-N问题

* @author "zhshl"

* @date2014-10-22

* @param

*/

public class Min_Heap {

private int heap[];

private int maxSize; 最多可容纳数目

private int n;///元素数目

/**

* @param num 堆的大小

*/

public Min_Heap(int num){

n=0;

maxSize=num;

heap=new int[maxSize];

}

/*

*//**

* 初始堆是一颗随意次序的全然二叉树,从(n-2)/2处開始向下调整

* @param heap

* @param n

*//*

public void createHeap(int[] heap2,int n){

heap=heap2;

for(int i=(n-2)/2;i>=0;i--){

///从(n-2)/2处開始向下调整

adjustDown(i,n-1);

}

}*/

/**

* 元素入堆

* @param v

*/

public void append(int v){

if(isFull()){

System.out.println("heap is full ,can't append elements !");

return ;

}

元素插在末尾

heap[n]=v;

n++;

///向上调整

adjustUp(n-1);

}

/**

* 取出堆顶元素

* @return

*/

public int serve(){

if(isEmpty()){

System.out.println("heap is empty!");

return Integer.MIN_VALUE;

}

int temp=heap[0];

用最后一个元素代替第一个元素

heap[0]=heap[n-1];

n--;

//向下调整

adjustDown(0, n-1);

return temp;

}

/**

* 求最大的n个数据

* @param data

* @param n

* @return null if n is bigger than the heap size, otherwise

*/

public int[] getTopN(int []data,int n){

heap=new int[n];

maxSize=n;

this.n=0;

///构建初始堆

for(int i=0;i

append(data[i]);

}

for(int i=n;i

假设比堆顶元素大,则替换堆顶元素,并调整

if(data[i]>heap[0]){

heap[0]=data[i];

adjustDown(0, n-1);

}

}

return heap;

}

/**

* 对元素i进行向下调整,用于删除元素时调整

* @param i

* @param j

*/

private void adjustDown(int i, int j) {

// TODO Auto-generated method stub

int child=2*i+1;

int temp=heap[i];///记录待调整的节点的值

while(child

在范围内进行遍历调整

if(heap[child]> heap[child+1]){

///假设左孩子比右孩子大, 则指向较小的右孩子

child++;

}

if(heap[child]>temp){

///假设较小的孩子都比自己大。则退出

break;

}

heap[(child-1)/2]=heap[child];

child=child*2+1;

}

循环结束。child指向终于位置的节点的左孩子

heap[(child-1)/2]=temp;

}

/**

* 将i处的元素向上调整为堆,用于插入时候

* @param i

*/

private void adjustUp(int i){

int temp=heap[i];

while(i>0&&heap[(i-1)/2]> temp){

///当父节点的值比temp大的时候,交换值

heap[i]=heap[(i-1)/2];

i=(i-1)/2;

}

heap[i]=temp;

}

/**

* 堆是否满了

* @return

*/

public boolean isFull(){

return n>=maxSize;

}

/**

* 是否为空堆

* @return

*/

public boolean isEmpty(){

return 0==n;

}

}

測试类:

package com.algorithm.test;

import com.algorithms.Min_Heap;

/**

* 最小堆測试类

* @author "zhshl"

* @date2014-10-22

*

*/

public class Min_Heap_Test {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

Min_Heap heap=new Min_Heap(10);

heap.append(2);

heap.append(2);

heap.append(13);

heap.append(21);

heap.append(2);

heap.append(2);

heap.append(53);

heap.append(6);

int temp;

while(!heap.isEmpty()){

temp=heap.serve();

System.out.println(temp);

}

System.out.println("\n\n 求top-N问题:");

int data[]={4,51,52,12,123,52,7643,234,123,33,44,2};

data=heap.getTopN(data, 5);

for(int i:data){

System.out.println(i);

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值