最小堆获取topK问题与堆的增删

/**
 * Created by  on 17/10/26.
 */
public class MinHeap {
    private int[] data;

    public MinHeap(int[] data){
        this.data=data;
    }
    //完全二叉树只有下标小于等于 (data.length/2 )-1才有叶子节点
    public void createHeap(){
        for(int i=(data.length)/2-1;i>=0;i--){
            heapIfy(i);
        }
    }

    public void heapIfy(int value){
        //获取左右孩子节点的下标
        int lchild=left(value);

        int rchild=right(value);

        int smallest=value;

        if(lchild<data.length&&data[lchild]<data[value]){
            smallest=lchild;
        }
        if(rchild<data.length&&data[rchild]<data[smallest]){
            smallest=rchild;
        }
        if(value==smallest){
            return;
        }
        //交换节点与左右孩子,使最小值上浮
        swap(value,smallest);
        //对交换过的节点进行heapIfy
        heapIfy(smallest);


    }

    public void setRoot(int vlaue){
        data[0]=vlaue;
        heapIfy(0);
    }

    public int getRoot(){
        return data[0];
    }
    //左孩子节点下标
    public int left(int value){
        return ((value+1)<<1)-1;
    }
    //右孩子节点下标
    public int right(int value){
        return (value+1)<<1;
    }

    public void swap(int i,int j){
        int tmp=data[i];

        data[i]=data[j];

        data[j]=tmp;
    }

    public static void main(String args[]) {
        //测试最小堆
        int[] value={10,100,12,73,45,32,11,23,55,34,90,21};
        MinHeap heap=new MinHeap(value);
        heap.createHeap();
        for(int i=0;i<value.length;i++){
            System.out.println(heap.data[i]+" ");
        }
        System.out.println("***");
        heap.setRoot(64);
        for(int i=0;i<value.length;i++){
            System.out.println(heap.data[i]+" ");
        }


    }
    //获取最大5个数
    public static int[] topK(int[] data,int k){
        int[] topk=new int[k];
        for(int i=0;i<k;i++){
            topk[i]=data[i];
        }
        //转传成最小堆
        MinHeap heap=new MinHeap(topk);

        for(int i=k;i<data.length;i++){
            int root=heap.getRoot();
            //替换掉最小值
            if(data[i]>root){
                heap.setRoot(data[i]);
            }

        }
        return topk;


    }


}
package boke.heap1;  
  
/** 
 * 堆结点 
 *  
 * @since jdk1.5及其以上 
 * @author 毛正吉 
 * @version 1.0 
 * @date 2010.05.24 
 *  
 */  
public class Node {  
    private int iData; // 结点数据是整型  
  
    public Node(int key) {  
        iData = key;  
    }  
  
    /** 
     * setKey 
     *  
     * @param id 
     */  
    public void setKey(int id) {  
        iData = id;  
    }  
  
    /** 
     * getKey 
     *  
     * @return 
     */  
    public int getKey() {  
        return iData;  
    }  
}  

2. 最小堆 

Java代码  收藏代码
package boke.heap1;  
  
import boke.heap.Node;  
  
/** 
 * 最小堆 
 *  
 * @since jdk1.5及其以上 
 * @author 毛正吉 
 * @version 1.0 
 * @date 2010.05.24 
 *  
 */  
public class MinHeap {  
    private Node[] heapArray; // 堆容器  
    private int maxSize; // 堆得最大大小  
    private int currentSize; // 堆大小  
  
    public MinHeap(int _maxSize) {  
        maxSize = _maxSize;  
        heapArray = new Node[maxSize];  
        currentSize = 0;  
    }  
  
    /** 
     * 自上而下调整 
     *  
     * @param start 
     * @param endOfHeap 
     */  
    public void filterDown(int start, int endOfHeap) {  
        int i = start;  
        int j = 2 * i + 1; // j是i的左子女位置  
        Node temp = heapArray[i];  
  
        while (j <= endOfHeap) { // 检查是否到最后位置  
            if (j < endOfHeap // 让j指向两子女中的小者  
                    && heapArray[j].getKey() > heapArray[j + 1].getKey()) {  
                j++;  
            }  
            if (temp.getKey() <= heapArray[j].getKey()) { // 小则不做调整  
                break;  
            } else { // 否则小者上移,i,j下降  
                heapArray[i] = heapArray[j];  
                i = j;  
                j = 2 * j + 1;  
            }  
        }  
        heapArray[i] = temp;  
    }  
  
    /** 
     * 自下而上的调整:从结点start开始到0为止,自下向上比较,如果子女的值小于双亲结点的值则互相交换 
     *  
     * @param start 
     */  
    public void filterUp(int start) {  
        int j = start;  
        int i = (j - 1) / 2;  
        Node temp = heapArray[j];  
  
        while (j > 0) { // 沿双亲结点路径向上直达根节点  
            if (heapArray[i].getKey() <= temp.getKey()) {// 双亲结点值小,不调整  
                break;  
            } else {// 双亲结点值大,调整  
                heapArray[j] = heapArray[i];  
                j = i;  
                i = (i - 1) / 2;  
            }  
            heapArray[j] = temp; // 回送  
        }  
    }  
  
    /** 
     * 堆中插入结点 
     *  
     * @param key 
     * @return 
     * @throws MinHeapException 
     */  
    public boolean insert(int key) throws MinHeapException {  
        boolean bool = true;  
        if (isFull()) {  
            bool = false;  
            throw new MinHeapException("MinHeap is full!");  
        } else {  
            Node newNode = new Node(key);  
            heapArray[currentSize] = newNode;  
            filterUp(currentSize);  
            currentSize++;  
        }  
        return bool;  
    }  
  
    /** 
     * 删除堆中的最小值 
     *  
     * @return 
     * @throws MinHeapException 
     */  
    public Node removeMin() throws MinHeapException {  
        if (isEmpty()) {  
            throw new MinHeapException("MinHeap is empty!");  
        }  
        Node root = heapArray[0];  
        heapArray[0] = heapArray[currentSize - 1];  
        currentSize--;  
        filterDown(0, currentSize - 1);  
        return root;  
    }  
  
    /** 
     * 按某种格式输出堆 
     */  
    public void displayHeap() {  
        System.out.print("heapArray: ");  
        for (int i = 0; i < currentSize; i++) {  
            if (heapArray[i] != null) {  
                System.out.print(heapArray[i].getKey() + " ");  
            } else {  
                System.out.print("-- ");  
            }  
        }  
        System.out.println();  
  
        int nBlanks = 32; // heap format  
        int itemsPerRow = 1;  
        int column = 0;  
        int j = 0; // current item  
        String dots = "...............................";  
        System.out.println(dots + dots); // dotted top line  
  
        while (currentSize > 0) { // for each heap item  
            if (column == 0) { // first item in row  
                for (int k = 0; k < nBlanks; k++) { // preceding blanks  
                    System.out.print(" ");  
                }  
            }  
            System.out.print(heapArray[j].getKey()); // display item  
  
            if (++j == currentSize) { // done?  
                break;  
            }  
  
            if (++column == itemsPerRow) { // end of row?  
                nBlanks /= 2; // half the blanks  
                itemsPerRow *= 2; // twice the items  
                column = 0; // start over on  
                System.out.println(); // next row  
            } else { // next item on row  
                for (int k = 0; k < nBlanks * 2 - 2; k++) {  
                    System.out.print(' '); // interim blanks  
                }  
            }  
        }  
        System.out.println("\n" + dots + dots);  
    }  
  
    public boolean isEmpty() {  
        return currentSize == 0;  
    }  
  
    public boolean isFull() {  
        return currentSize == maxSize;  
    }  
  
    public void makeEmpty() {  
        currentSize = 0;  
    }  
}  

3. 堆异常 

Java代码  收藏代码
package boke.heap1;  
  
/** 
 * 堆异常 
 *  
 * @since jdk1.5及其以上 
 * @author 毛正吉 
 * @version 1.0 
 * @date 2010.05.24 
 *  
 */  
public class MinHeapException extends Exception {  
    public MinHeapException() {  
        super("MinHeapException");  
    }  
  
    public MinHeapException(String exMsg) {  
        super(exMsg);  
    }  
}  

4.  最小堆应用测试 

Java代码  收藏代码
package boke.heap1;  
  
import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader;  
  
/** 
 * 最小堆应用测试 
 *  
 * @since jdk1.5及其以上 
 * @author 毛正吉 
 * @version 1.0 
 * @date 2010.05.24 
 *  
 */  
public class MinHeapApp {  
  
    /** 
     * @param args 
     * @throws IOException 
     * @throws MinHeapException 
     */  
    public static void main(String[] args) throws IOException, MinHeapException {  
        int value, value2;  
        MinHeap hp = new MinHeap(31);  
        boolean success;  
  
        hp.insert(53);  
        hp.insert(17);  
        hp.insert(78);  
        hp.insert(9);  
        hp.insert(45);  
        hp.insert(65);  
        hp.insert(87);  
        hp.insert(23);  
  
        while (true) {  
            System.out.print("Enter first letter of ");  
            System.out.print("show, insert, remove: ");  
            int choice = getChar();  
  
            switch (choice) {  
            case 's':  
                hp.displayHeap();  
                break;  
            case 'i':  
                System.out.print("Enter value to insert: ");  
                value = getInt();  
                success = hp.insert(value);  
                if (!success) {  
                    System.out.println("Can't insert; heap is full");  
                }  
                break;  
            case 'r':  
                if (!hp.isEmpty()) {  
                    hp.removeMin();  
                } else {  
                    System.out.println("Can't remove; heap is empty");  
                }  
                break;  
            default:  
                System.out.println("Invalid entry\n");  
            }  
        }  
  
    }  
  
    /** 
     * 获得控制台输入流 
     *  
     * @return 
     * @throws IOException 
     */  
    public static String getString() throws IOException {  
        return new BufferedReader(new InputStreamReader(System.in)).readLine();  
    }  
  
    /** 
     * 获得控制台输入字符 
     *  
     * @return 
     * @throws IOException 
     */  
    public static char getChar() throws IOException {  
        return getString().charAt(0);  
    }  
  
    /** 
     * 获得控制台输入整型 
     *  
     * @return 
     * @throws NumberFormatException 
     * @throws IOException 
     */  
    public static int getInt() throws NumberFormatException, IOException {  
        return Integer.parseInt(getString());  
    }  
  
}  


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值