zoukankan      html  css  js  c++  java
  • 堆算法简介

    堆是有特殊顺序的完全二叉树。常用数组存储。

    以最小堆为例。其父节点,要小于左右两个子节点。如此递归定义。

    数组存储。第i个节点的父节点是 (i-1)/2, 左子节点是2*i+1, 右子节点是2*i+2。当然是在考虑到数组边界的情况下。

    其实堆运算很简单。只要清楚存储结构,明白插入,删除,建立时调整方向:上滑还是下滑。很容易就写出来了。

    不过要注意减少数组元素移动次数。

    下面给出java实现代码

    package com.company;
    
    /**
     * Created by zqiguo on 2017/3/11.
     */
    public class Heap {
        private int heapSize;
        private int currentSize;
        private int[] heapArray;
    
        /**
         * siftDown algorithm when build a heap from an array
         * if you know the storage of a complete binary tree well, it's easy.
         * The point is how to reduce the move of array element.
         * @param pos int,  the position to start siftDown
         */
        private void siftDown(int pos){
            int tmp = heapArray[pos];
            while (pos * 2 + 1 < currentSize){
                int minIndex = pos * 2 + 1;
                if (minIndex + 1 < currentSize){
                    minIndex = heapArray[minIndex] <= heapArray[minIndex+1] ? minIndex : minIndex+1;
                }
                if (heapArray[minIndex] < tmp){
                    heapArray[pos] = heapArray[minIndex];
                    pos = minIndex;
                }else {
                    break;
                }
            }
            heapArray[pos] = tmp;
        }
    
        /**
         * return the top of the heap
         * @return the top of the heap
         */
        public int getTop(){
            return heapArray[0];
        }
    
        public void printHeap(){
            for (int i = 0; i < currentSize; i++)
            {
                System.out.printf(heapArray[i] + " ");
            }
            System.out.println();
        }
        public Heap(){
            heapSize = 5;
            currentSize = 0;
            heapArray = new int[heapSize];
        }
    
        /**
         * build a heap from an array.
         * @param array
         */
        public Heap(int[] array){
            currentSize = array.length;
            if (heapSize < currentSize){
                heapArray = new int[currentSize];
                heapSize = currentSize;
            }
            for (int i = 0; i < currentSize; i++) {
                heapArray[i] = array[i];
            }
            int lastParent = (currentSize - 2) / 2;
            while (lastParent >= 0){
                siftDown(lastParent--);
            }
        }
    
        /**
         * insert an element to heap. auto resize the heapArray, if full.
         * @param element
         * @return
         */
        public boolean insert(int element){
            if (currentSize == heapSize){
                int[] tmp = new int[heapSize*2];
                for (int i = 0; i < currentSize; i++) {
                    tmp[i] = heapArray[i];
                }
                heapArray = tmp;
                heapSize = tmp.length;
            }
            heapArray[currentSize] = element;
            siftUp(currentSize);
            currentSize++;
            return true;
        }
    
        /**
         * delete the top of the heap
         * @return the top of heap
         */
        public int delete(){
            if (currentSize == 0){
                System.out.println("The heap is empty!");
                return -1;
            }else {
                int tmp = heapArray[0];
                heapArray[0] = heapArray[currentSize-1];
                currentSize--;
                siftDown(0);
                return tmp;
            }
        }
    
        /**
         * siftup adjust, used by insert.
         * @param start
         */
        private void siftUp(int start){
            int tmp = heapArray[start];
            while (start > 0){
                int parentIndex = (start-1) / 2;
                if (heapArray[parentIndex] > tmp){
                    heapArray[start] = heapArray[parentIndex];
                    start = parentIndex;
                }else {
                    break;
                }
            }
            heapArray[start] = tmp;
        }
    
        public static  void main(String[] args){
            int [] array = new int[]{7,6,5,4,3,2,1};
            Heap heap = new Heap(array);
            heap.printHeap();
            heap.insert(0);
            heap.printHeap();
            heap.delete();
            heap.printHeap();
        }
    }
  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/zqiguoshang/p/6537150.html
Copyright © 2011-2022 走看看