基本排序之堆排序

堆排序:

它可以看做是完全二叉树的结构。

分为大根堆和小根堆。如果父节点大于左右节点就是大根堆,父节点小于左右子节点就是小根堆。本文写大根堆的排序。

设当前节点为i的话:

子节点:2*i+1,2*i+2

父节点:(i-1)/2

概述:

(1)建立大根堆(HeapInsert):把当前节点和父节点比较,如果大于父节点,那么就上升。如果小于父节点,那么不做变动。

(2)调整堆(Heapify):建立大根堆后,现在的堆每一个父节点都大于其左右两个子节点。那么最顶部就是最大的值。此时应当:

i)        把最顶部的元素和最后一个元素交换,让最大的元素处于末尾。

ii)       调整,如果现在最顶部元素的值不是最大值,也就是说,把它和它的左右子节点中大的那个节点比较,如果小于这个子节点,那么这个子节点和它交换,父节点下沉。

iii)       不断比较,直至不能下沉为止。然后重复前两步操作,直至整个数组排好。

其中排好的标志:我们先定义个一个长度表示建立大根堆之后的数组长度,每一次(2)(i)之后,表示一个数排好了,那么这个数组长度就减去1,如果这个数组长度为0,那么排序也就结束了。

 

时间复杂度:

  O(NlogN)

 

算法稳定性:

  不稳定算法。

 

代码如下:

#include <iostream>
#include <vector>
#include <random>
using namespace std;


class HeapSort_
{
public:
    void HeapSort(vector<int> &v);
    void HeapInsert(vector<int> &v,int index);
    void Heapify(vector<int> &v, int size);
    void swap(vector<int> &v, int a, int b);
};

void HeapSort_::HeapSort(vector<int> &v)
{
    if (v.size() < 2)
    {
        return;
    }
    for (int i = 0; i < v.size(); i++)
    {
        HeapInsert(v,i);
    }
    for (int size = v.size()-1; size > 0; size--)
    {
        swap(v, 0, size);
        Heapify(v, size);
    }
    
}

//建立大根堆
void HeapSort_::HeapInsert(vector<int> &v,int index)
{
    //如果大于父节点就交换,使得大的值一直处于上部直至顶部
    while (v[index] > v[(index - 1) / 2])
    {
        swap(v, index, (index - 1) / 2);
        index = (index - 1) / 2;
    }
}

void HeapSort_::Heapify(vector<int> &v,int size)
{
    int index = 0;
    int left = index * 2 + 1;
    //如果没有左节点就不判断,所以left<size
    while (left < size)
    {
        //如果存在右节点,那么返回比较大的数的下标
        int max = left + 1 < size && v[left + 1] > v[left] ? left + 1 : left;
        max = v[max] > v[index] ? max : index;
        //如果子节点小于父节点就返回index,说明大的值还是父节点
        if (max == index)
            break;
        //如果子节点大于父节点,那么交换,并且把子节点的位置赋值给当前位置index作为父节点位置
        //左节点重新赋值
        swap(v, max, index);
        index = max;
        left = 2 * index + 1;
    }
}

void HeapSort_::swap(vector<int> &v, int a, int b)
{
    int temp = v[a];
    v[a] = v[b];
    v[b] = temp;
}
int main()
{
    HeapSort_ h;
    static default_random_engine e;
    static uniform_int_distribution<int> u(-34, 87);
    vector<int> v(15);
    for (int i = 0; i < 15; i++)
    {
        v[i] = u(e);
    }
    h.HeapSort(v);
    for (int i = 0; i < 15; i++)
    {
        cout << v[i] << " ";
    }
    return 0;
}

 

posted @ 2018-01-25 15:40  _NewMan  阅读(187)  评论(0编辑  收藏  举报