堆排序

堆排序为常见排序算法之一,为不稳定排序,且在排序过程中需要额外的空间

概念

 

创建一个大顶堆,然后将根元素与最后一个元素交换位置(该元素最终位置),堆长度减一,然后调整树再次成为大顶堆,然后依次减少堆长度直到为1

 构造大顶堆 小顶堆

在使用堆排序时,需要构造大顶堆,小顶堆,构造大顶堆代码如下:

void heapify(vector<int>& data, int start, int end)
{
    int dad = start;
    int son = 2 * dad + 1;
    while (son <= end)
    {
        if (son + 1 <= end && data[son] < data[son + 1])
            son++;
        if (data[dad] > data[son])
            return;
        else
        {
            swap(data[dad], data[son]);
            dad = son;
            son = son * 2 + 1;
        }
    }
}

void max_heap(vector<int>& data)
{
    int length = data.size();
    for (int i = length / 2 - 1; i >= 0; i--)//从最后一个父节点,倒序整理
    {
        heapify(data, i, length - 1);
    }

    cout << "create heap" << endl;
    for (auto val : data)
    {
        cout << val << endl;
    }
}

关于为什么最后一个根节点的index为n/2-1,见:https://www.cnblogs.com/malw/p/10542557.html

堆排序代码

//构造大顶堆
void max_heapify(vector<int>& data,int start,int end)
{
    int dad = start;
    int son = 2 * dad + 1;
    while (son <= end)
    {
        if ((son + 1) <= end && data[son] < data[son + 1])//从两个节点中找到较大的
            son++;
        if (data[dad] > data[son])    //如果父节点大于子节点,则表示调整结束,return
            return;
        else
        {
            swap(data[dad], data[son]);
            dad = son;
            son = son * 2 + 1;
        }
    }
}

void heapSort(vector<int>& data)
{
    int length = data.size();
    for (int i = length / 2 - 1; i >= 0; i--)//从最后一个父节点开始构造,倒序
    {
        max_heapify(data, i, length - 1);
    }
    
    for (auto val : data)
        cout << val << endl;

    cout << "========" << endl;
    for (int i = length-1; i >=0; i--)
    {
        //交换根、最后一个节点
        swap(data[0], data[i]);
        //构造大顶堆
        max_heapify(data, 0, i - 1);
    }
}
原文地址:https://www.cnblogs.com/zyk1113/p/14241491.html