1. 程式人生 > >STL中的heap演算法

STL中的heap演算法

  就排序而言,heap是一種特別的元素組織方式,應用於heap排序法。Heap可以被視為一個以序列式集合實現而成的二叉樹。具有兩大性質:

  1. 第一個元素總是最大
  2. 總是能夠在對數時間內增加或者移除一個元素。

======
  Heap是實現優先順序佇列的一個理想結構,因此heap演算法也被priority_queue容器使用。為了處理heap,STL提供了四個演算法:

  1. make_heap():將某區間內的元素轉化為heap
  2. push_heap():對heap增加一個元素
  3. pop_heap():對heap取出下一個元素
  4. sort_heap():將heap轉化為一個已排序序列。

同樣的,可以給上述函式傳入一個二元的謂詞作為排序準則。預設的排序準則是operator<。

void make_heap(RandomAccessIterator beg,RandomAccessIterator end/*,BinaryPredicate op*/)
  • 兩種形式都將[beg,end)區間內的元素轉化為heap
  • 複雜度:線性,至多執行3*n次比較
void push_heap(RandomAccessIterator beg,RandomAccessIterator end/*,BinaryPredicate op*/)
  • 將end之前的最後一個元素加入原本就是heap的[beg,end-1)區間內,使整個[beg,end)區間成為一個heap
  • 呼叫者必須保證
    ,進入函式時,[beg,end-1)區間內的元素(在相同的排序準則下)原本便已形成一個heap,而新元素緊隨其後
  • 複雜度:對數
void pop_heap(RandomAccessIterator beg,RandomAccessIterator end/*,BinaryPredicate op*/)
  • 將heap[beg,end)內的最高元素(即第一個元素)移到最後位置,並將[beg,end-1)內的元素組織起來,從新組成heap
  • 呼叫者必須保證,進入函式時,[beg,end)區間內的元素(在相同的排序準則下)原本便已形成一個heap
  • 複雜度:對數
void sort_heap(RandomAccessIterator beg,RandomAccessIterator end/*,BinaryPredicate op*/
)
  • 將heap[beg,end)轉換為一個已排序序列
  • 此演算法一旦結束,該區間就不再是一個heap
  • 呼叫者必須保證,進入函式時,[beg,end)區間內的元素(在相同的排序準則下)原本便已形成一個heap
int main()
{
    vector<int> coll;
    insertElements(coll, 3, 7);
    insertElements(coll, 5, 9);
    insertElements(coll, 1, 4);

    printElements(coll,"on entry: ");

    make_heap(coll.begin(), coll.end());

    printElements(coll,"after make_heap(): ");

    pop_heap(coll.begin(), coll.end());
    coll.pop_back();

    printElements(coll, "after pop_heap(): ");

    coll.push_back(17);
    push_heap(coll.begin(), coll.end());

    printElements(coll, "after push_heap(): ");

    sort_heap(coll.begin(), coll.end());

    printElements(coll, "after sort_heap(): ");

    return 0;




}

這裡寫圖片描述

呼叫make_heap()之後,元素被排序為heap:

9 8 6 7 7 5 5 3 6 4 1 2 3 4

如果把這些元素轉換為二叉樹
這裡寫圖片描述
可以看到每個元素都小於或者等於其父親結點。