堆算法简介

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

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

数组存储。第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();
    }
}
时间: 2024-11-05 13:26:47

堆算法简介的相关文章

图解堆算法、链表、栈与队列(Mark)

原文地址: 图解堆算法.链表.栈与队列(多图预警) 堆(heap),是一类特殊的数据结构的统称.它通常被看作一棵树的数组对象.在队列中,调度程序反复提取队列中的第一个作业并运行,因为实际情况中某些时间较短的任务却可能需要等待很长时间才能开始执行,或者某些不短小.但很重要的作业,同样应当拥有优先权.而堆就是为了解决此类问题而设计的数据结构.--

【万字总结】图解堆算法、链表、栈与队列(多图预警)

转自:http://blog.csdn.net/nomasp/article/details/50349172 堆算法 什么是堆 堆(heap),是一类特殊的数据结构的统称.它通常被看作一棵树的数组对象.在队列中,调度程序反复提取队列中的第一个作业并运行,因为实际情况中某些时间较短的任务却可能需要等待很长时间才能开始执行,或者某些不短小.但很重要的作业,同样应当拥有优先权.而堆就是为了解决此类问题而设计的数据结构. 二叉堆是一种特殊的堆,二叉堆是完全二叉树或者近似完全二叉树,二叉堆满足堆特性:父

STL中heap算法(堆算法)

 ①push_heap算法 以下是push_heap算法的实现细节.该函数接收两个迭代器,用来表现一个heap底部容器(vector)的头尾,而且新元素已经插入究竟部的最尾端. template <class RandomAccessIterator> inline void push_heap(RandomAccessIterator first,RandomAccessIterator last) { //注意,此函数被调用时,新元素应已置于底部容器的最尾端 _push_heap_au

TF-IDF算法简介

TF-IDF算法全称为term frequency–inverse document frequency.TF就是term frequency的缩写,意为词频.IDF则是inverse document frequency的缩写,意为逆文档频率. 该算法在信息处理中通常用来抽取关键词.比如,对一个文章提取关键词作为搜索词,就可以采用TF-IDF算法. 要找出一篇文章中的关键词,通常的思路就是,就是找到出现次数最多的词.如果某个词很重要,它应该在这篇文章中多次出现.于是,我们进行"词频"

最小生成树 kruskal算法简介

生成树--在一个图中的一个联通子图  使得所有的节点都被(访问) 最小生成树 (MST) 即联通子图的总代价(路程)最小 已知的一个图 有n个点 m条边 kruskal的算法如下 先对边从小到大排序 从最小的边起,不停的合并这条边的两个节点到一个集合,如果这条边的两个节点已经在一个集合里,则无视,否则形成回路(显然错误)直到所有的节点并到一个集合里 这里需要用到并查集来合并节点 1 int cmp(const int i,const int j) { 2 return w[i] < w[j];

AES算法简介

AES算法简介 一. AES的结构 1.总体结构 明文分组的长度为128位即16字节,密钥长度可以为16,24或者32字节(128,192,256位).根据密钥的长度,算法被称为AES-128,AES-192或者AE-256. 2.明文密钥组织方式 3.一些相关的的术语定义和表示 • 状态(State):密码运算的中间结果称为状态. • State的表示:状态用以字节为基本构成元素的矩阵阵列来表示,该阵列有4行,列数记为Nb. Nb=分组长度(bits)÷ 32.Nb可以取的值为4,对应的分组长

Java哈希散列算法简介 - MD5 &amp; SHA-512

Java哈希散列算法简介 - MD5 & SHA-512 在日常的开发工作中,我们常常会碰到这样的一个场景:我们需要有一种可靠的行之有效的方法来检验跟判断数据在传输过程当中的完整性.最常见的一种情况就是当我们传输文件的时候,由于网络故障或者其他的一些因素,可能会出现我们下载下来的文件不完整,这给我们日常的开发和维护带了一些难题:另外的一个较为常用的场景就是:有没有一种行之有效的方法让我们可以很方便的判断服务器上的文件是不是有最新的数据更新,比如我们现在的移动Hybird App开发,我们经常会发

MD5算法 简介

MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2.MD3和MD4发展而来.MD5算法的使用不需要支付任何版权费用. MD5功能 l 输入任意长度的信息,经过处理,输出为128位的信息(数字指纹): l 不同的输入得到的不同的结果(唯一性): l 根据128位的输出结果不可能反推出输入的信息(不可逆): MD5用途 1.防止被篡改: 1)比如发送一个电子文档,发送前,我先得到MD5的输出结果a.然后在对方收到电子文档后,对方也得到一个M

算法简介及算法分析

算法简介及算法分析 算法简介 算法的定义: 算法是对特定问题求解步骤的一种描述,是指令的有限序列.(所以说只要满足上述条件,即使很简单的一个循环也是算法) 算法具备5个特征: 输入 输出 有穷性 确定性 可行性 什么是好算法: 正确性 鲁棒性 简单性 抽象分级 高效性 算法分析: 高效性是评价一个算法是否是好算法的重要标准,那么我们怎么判断算法是否高效呢?有的人说,把算法用程序语言实现一下,再输入多个测试数据实际检测运行速度(时间频度)和空间开销就好了呗!这种事后统计的方法并不能准确检测,它牵扯