七大排序算法---堆排序

堆排序


第一步:根據初始輸入數據,利用堆的調整算法 siftDown() 形成初始堆
第二步:通過元素交換和重新調整堆進行排序。

建堆(大堆)

輕鬆教你建堆→
上面鏈接是建立小堆的,建立大堆在理解小堆之後,也是能輕鬆寫出來的。
這裏寫圖片描述

代碼實現

//構造函數
maxHeap(T * arr, int sz)
    {
        heap = new T[sz];
        heap = arr;
        heapSize = sz;
        _currentSize = sz;
    /*  for (int i = 0; i < sz; i++)
        {
            heap[i] = arr[i];
        }*/

        //從 (sz-2)/2 位置開始循環下滑
        for (int j = (sz - 2) / 2; j >= 0; j--)
        {
            siftDown(j, sz);
        }
    }
    //下滑算法,利用下滑算法輕鬆建堆
void siftDown(int currentPos, int currentSize)
    {
        int father = currentPos;
        int child = father * 2 + 1;
        T temp = heap[father];

        while (child < currentSize)
        {
            if ((child + 1) < currentSize && heap[child] < heap[child + 1])
                child = child + 1;
            if (temp < heap[child])
            {
                heap[father] = heap[child];
                father = child;
                child = father * 2 + 1;
            }
            else
                break;

        }
        heap[father] = temp;

    }

排序

當我們已經建立大堆之後,堆頂的第一個元素 heap[0] 具有最大的排序碼,將 heap[0]heap[n - 1] 對調,把具有最大排序碼的元素交換到最後,再對前面的 n - 1 個元素,使用堆的調整算法 siftDown(0 , n - 1) ,重新建立大堆。

這裏寫圖片描述
代碼實現

#include<iostream>
using namespace std;


template<class T>
class maxHeap
{
public:
    //構造函數
    maxHeap(int sz)
    :heap(NULL)
    , heapSize(sz)
    {}

    //構造函數
    maxHeap(T * arr, int sz)
    {
        heap = new T[sz];
        heap = arr;
        heapSize = sz;
        _currentSize = sz;
    /*  for (int i = 0; i < sz; i++)
        {
            heap[i] = arr[i];
        }*/

        //從 (sz-2)/2 位置開始循環下滑
        for (int j = (sz - 2) / 2; j >= 0; j--)
        {
            siftDown(j, sz);
        }
    }

    //堆排序
    void heapSort()
    {
        currentPos = _currentSize - 1;
        T currentSize = _currentSize;
        while (currentPos > 0)
        {
            T temp = heap[0];
            heap[0] = heap[currentPos];
            heap[currentPos] = temp;
            currentSize--;
            for (int i = (currentSize - 2) / 2; i >= 0; i--)
            {
                siftDown(i, currentSize);
            }
            currentPos--;
        } 

    }

    void showHeap()
    {
        for (int i = 0; i < _currentSize; i++)
            cout << heap[i] << " ";
    }


private:
    T * heap;//存放堆的數組
    int heapSize;//堆的大小
    int _currentSize;//堆的當前大小
    int currentPos;//當前操作位置
    //下滑函數構成最大堆
    void siftDown(int currentPos, int currentSize)
    {
        int father = currentPos;
        int child = father * 2 + 1;
        T temp = heap[father];

        while (child < currentSize)
        {
            if ((child + 1) < currentSize && heap[child] < heap[child + 1])
                child = child + 1;
            if (temp < heap[child])
            {
                heap[father] = heap[child];
                father = child;
                child = father * 2 + 1;
            }
            else
                break;

        }
        heap[father] = temp;

    }


};



int main()
{
    int arr[6] = { 3, 2, 0, 9, 4, 5 };
    maxHeap<int> s(arr, 6);
    s.heapSort();
    s.showHeap();
    return 0;
}

時間複雜度

時間複雜度:O(1)
穩定性:不穩定排序算法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章