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

堆排序


第一步:根据初始输入数据,利用堆的调整算法 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)
稳定性:不稳定排序算法

猜你喜欢

转载自blog.csdn.net/qq_37934101/article/details/81007772