• Heap算法详解


    算法描述

    就Heap算法而言,heap是一种特殊的元素组织方式,应用于heap排序法(heapsort).heap可以被视为一个以序列式群集实作而成的二叉树,本文以“大堆顶”为例进行讨论,heap具有两大性质:

    1、第一个元素总是最大。

    2、总是能够在对数时间内增加或移除一个元素。

    为了处理heap,STL提供四种算法:

    1、make_heap()     将某区间内的元素转化成heap

    2、push_heap()      对着heap增加一个元素

    3、pop_heap()        对着heap取出下一个元素

    4、sort_heap()        将heap转化为一个已序群集 (此后它就不再是heap 了)。

    make_heap

    void
    make_heap(RandomAccessIterator beg, 
    		  RandomAccessIterator end);
    void 
    make_heap(RandomAccessIterator beg, 
    		  RandomAccessIterator end,
    		  BinaryPredicate op);
    • 两种形式都将区间[beg, end)内的元素都转化为heap。
    • op是可选的二元判断式,被视为排序准则:op(elem1, elem2)

    push_heap

    void
    push_heap(RandomAccessIterator beg, 
    		  RandomAccessIterator end);
    void 
    push_heap(RandomAccessIterator beg, 
    		  RandomAccessIterator end,
    		  BinaryPredicate op);
    • 两种形式都将end之前的最后一个元素加入原本就是个heap的[beg, end -1)区间内,使整个区间[beg, end)称为一个heap
    • op是可选的二元判断式,被视为排序准则:op(elem1, elem2)
    • 调用者保证,进入函数时,区间[beg, end - 1)内的元素原本便已经是一个heap,而新元素紧跟其后。

    pop_heap

    void
    pop_heap(RandomAccessIterator beg, 
    		 RandomAccessIterator end);
    void 
    pop_heap(RandomAccessIterator beg, 
    		 RandomAccessIterator end,
    		 BinaryPredicate op);

    • 以上两种形式都是将heap[beg, end)内的最高元素,即第一个元素,移到最后位置。并将剩余区间[beg, end -1)内的元素组织起来,成为一个新的heap。
    • op是个可以选的二元判断式,被当做排序准则:op(elem1, elem2).
    • 调用者必须保证,进入函数时,区间[beg, end)内的元素原本便已经形成一个heap.

    sort_heap

    void
    sort_heap(RandomAccessIterator beg, 
    		  RandomAccessIterator end);
    void 
    sort_heap(RandomAccessIterator beg, 
    		  RandomAccessIterator end,
    		  BinaryPredicate op);

    • 以上两种形式都是可以将heap[beg, end)转换为一个已序(sorted)序列
    • op是个二元判断式,被视为排序准则:op(elem1, elem2)
    • 调用者必须保证,进入函数时,区间[beg, end)内的元素原本便已经形成一个heap
    • 此算法一旦执行结束,该区间就不再是个heap了。
    heap算法使用范例
    /****************************************************************
    *函数名称:HeapTest
    *功    能:Heap算法使用实例
    *作    者:Jin
    *日    期:2016年7月5日
    ****************************************************************/
    void HeapTest()
    {
        vector<int> nVector;
        InsertElements(nVector, 3, 7);
        InsertElements(nVector, 5, 9);
        InsertElements(nVector, 1, 4);
    
        PrintElements(nVector, "on entry: ");
    
        //convert collection into heap
        make_heap(nVector.begin(), nVector.end());
        PrintElements(nVector, "after make_heap: ");
    
        //pop next element out of heap
        pop_heap(nVector.begin(), nVector.end());
        nVector.pop_back();
        PrintElements(nVector, "after pop_heap(): ");
    
        //push new element into the heap
        nVector.push_back(17);
        push_heap(nVector.begin(), nVector.end());
        PrintElements(nVector, "after push_heap(): ");
    
        // convert heap into a sorted collection
        // Note: after the call it is no longer a heap
        sort_heap(nVector.begin(), nVector.end());
        PrintElements(nVector, "after sort_heap(): ");
    }
    输出结果:  


    从上面可知,调用了make_heap之后区间内的元素就变成堆元素了,将其转换为二叉树形式如图1,将会发现每个父节点都会大于子节点。push_heap()和pop_heap()虽然会替换元素,但二叉树的性质保持不变(每个子节点不会大于其父节点)。

        图1 二叉树


  • 相关阅读:
    list容器的sort函数
    c++ vector迭代器删除元素
    vs中属性页常用配置介绍2
    vs中属性页常用配置介绍
    error 不是类或命名空间
    实习代码编写中,一些有用的经验
    vs2015环境下生动动态链接库及使用
    STL容器使用的时机
    c++文件和流
    c++接口(抽象类,虚函数,纯虚函数)
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468407.html
Copyright © 2020-2023  润新知