堆排序,C++模板編程

來源:互聯網
上載者:User

明天就要去參加百度的筆試了,現在來抱抱佛教。

 

理論來自:簡明現代魔法

在程式設計相關領域,堆(Heap)的概念主要涉及到兩個方面:

  • 一種資料結構,邏輯上是一顆完全二叉樹,儲存上是一個數組對象(二元堆積)。
  • 垃圾收集儲存區,是軟體系統可以編程的記憶體地區。

本文所說的堆,指的是前者。

堆排序的時間複雜度是O(nlgN),與快速排序達到相同的時間複雜度。但是在實際應用中,我們往往採用快速排序而不是堆排序。這是因為快速排序的一個好的實現,往往比堆排序具有更好的表現。堆排序的主要用途,是在形成和處理優先順序隊列方面。另外,如果計算要求是類優先順序隊列(比如,只要返回最大或者最小元素,只有有限的插入要求等),堆同樣是很適合的資料結構。

基礎知識

堆一般用數組表示,比如數組A數組的長度Length(A),堆在數組中的元素個數HeapSize(A)。一般說來,HeapSize(A) <= Length(A),因為數組A當中可能有一些元素不在堆中。

假設節點I是數組A中下標為i的節點。

  • Parent(i) : return Floor(i/2); //I的父節點下標,Floor(i)表示比i小的最大整數。
  • Left(i) : return 2*i; //I的左子節點
  • Right(i) : return 2*i+1; //I的右子節點

含有n個元素的堆A的高度是: Floor(lgn)。

堆的基本操作
  • MaxHeapify( A, i ):

    保持堆的性質。假設數組A和下標i,假定以Left(i)和Right(i)為根結點的左右兩棵子樹都已經是最大堆,節點i的值可能小於其子節點。調整節點i的位置。

  • BuildMaxHeap( A ):

    從一個給定的數組建立最大堆。子數組A[ floor(n/2)+1 .... ... n]中的元素都是樹的分葉節點(完全二叉樹的基本性質)。從索引 ceiling(n/2)開始一直到1,對每一個元素都執行MaxHeapify,最終得到一個最大堆。

  • 堆排序 HeapSort( A ):

    堆排序演算法的基本思想是,將數組A建立為一個最大堆,然後交換堆的根(最大元素)和最後一個分葉節點x,將x從堆中去掉形成新的堆A1,然後重複以上動作,直到堆中只有一個節點。

  • 優先順序隊列演算法-增加某元素的值(優先順序) : HeapIncreaseKey( A, i, key )

    增加某一個元素的優先順序後(元素的值),該元素應該向上移動,才能保持堆的性質。

  • 優先順序隊列演算法-插入一個元素: Insert( S, x ) 將x元素插入到優先順序隊列S中。

    主要思路是,將堆的最後一個分葉節點之後,擴充一個為無窮小的新分葉節點,然後增大它的值為x的值。

 

本來我只打算隨便寫個小程式的,但是發現,可以寫個更通用的程式。以最小堆為例,說下建堆和排序的過程。

經過上面兩個步驟,就成功的建立了一個最小堆。排序的過程就是取出堆頂元素push到臨時數組,然後將堆頂元素和最後一個元素交換,再pop掉最後一個元素,直到堆中沒有元素。這樣就獲得了一個有序的數組,然後在複製到堆中。

完整程式如下:

//最小堆排序和最大堆排序#include <algorithm>#include <functional>#include <vector>#include <iostream>using namespace std;template<typename Type>class Heap{public:    Heap(const vector<Type>& a_array)    {        m_array.assign(a_array.begin(),a_array.end());    }    template<typename Compare>    void sort(Compare comp);    void printArray(const vector<Type>& a_array);private:    vector<Type> m_array;    //comp 為less<Type> 則大數下沉,建立最小堆,從小到大排序    //comp 為greater<Type> 則小數下沉,建立最大堆,從大到小排序    template<typename Compare>    void creatHeap(Compare comp);                //建立堆    template<typename Compare>    void downElement(int a_elem, Compare comp);    //下沉元素};template<typename Type>template<typename Compare>void Heap<Type>::sort(Compare comp){    printArray(m_array);    creatHeap(comp);                    //建堆    vector<Type> array;    for (int i = m_array.size() - 1; i >= 0; i--)    {        array.push_back(m_array[0]);    //保留堆頂        swap(m_array[0], m_array[i]);    //交換        m_array.pop_back();                //去掉最後一個元素        downElement(0,comp);            //將新的首元素下沉    }    printArray(array);    m_array.assign(array.begin(),array.end());}template<typename Type>template<typename Compare>void Heap<Type>::creatHeap(Compare comp){    //從最後一個非葉子節點開始,將每個父節點都調整為最小堆    for (int i=m_array.size()/2-1; i>=0; i--)    {        downElement(i, comp);    }}template<typename Type>template<typename Compare>void Heap<Type>::downElement(int a_elem, Compare comp)    //下沉元素{    int min;            //設定最小元素下標    int index = a_elem;    //當前下沉的元素下標    while (index*2+1 < m_array.size())//存在左節點    {        min = index*2+1;        if (index*2+2 < m_array.size())//存在右節點        {            //左右節點比較,選出最小的            if (comp(m_array[index*2+2],m_array[min]))            {                min = index*2+2;            }        }        //同子節點比較,若父節點最小則結束        if (comp(m_array[index],m_array[min]))        {            break;        }        else//選最小元素到父節點        {            swap(m_array[min],m_array[index]);            index = min;        }    }}template<typename Type>void Heap<Type>::printArray(const vector<Type>& a_array){    for (int i=0; i<a_array.size(); i++)    {        cout << a_array[i] << " ";    }    cout << endl;}int main(){    vector<int> array;    for (int i=10; i<20; i++)    {        array.push_back(i);    }    random_shuffle(array.begin(), array.end());//打亂順序    Heap<int> heap(array);    heap.sort(less<int>());    heap.sort(greater<int>());    return 0;}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.