【STL】堆

【STL】常用容器总结,带有复习性质的学习更有效率;


Heap】 在STL中不是以容器的方式呈现的,而是以算法的方式;

所谓堆,其实就是将数组假想成完全二叉树,满足某种规则的呈现。
某种规则就是堆顶(数组第一个元素)始终为最大或者最小的元素,还可以结合数组连续性的特性进行堆排序;

堆分为 max heap 和 min heap, STL默认的是 max heap , 所以下面实现的时候也会实现为最大堆;

在自己再次去实现它的时候,我们先来使用一下它;

#include 
#include 
#include 

using namespace std;

int main()
{
    int arr[] = {2,31,5,7,45,87};
    vector<int> v(arr, arr+6);
    make_heap(v.begin(), v.end());          //构造堆,看看第一个位置是否发生变化;
    cout<0]<99);
    push_heap(v.begin(), v.end());
    cout<0]<//新加入一个99


    sort_heap(v.begin(), v.end());   //堆排序
    for(int i = 0; i < v.size(); ++i)
    {
        cout<" ";
    }
    cout<cout<0]<//删除堆顶

    return 0;
}

分析: 上面就是STL提供的堆算法,一共四个

make_heap: 够建堆(最大),参数是一段迭代器区间;
push_heap: 插入元素后调整堆,前提是存在一个堆,新元素插在最后;
pop_heap : 删除堆顶元素,内部做了向下调整算法;
sort_heap: 堆排序,时间复杂度是nlogn;

如果仔细一点就会发现,后三个算法使用的前提都是make_heap, 上面的例子中,sort _heap 破坏了堆结构, 后面必须重新使用 make _heap 否则会报错, 或者出现不可预期的结果;

下面是我作为回顾敲的代码,作为巩固;

//实现堆和堆排序

#include 
#include 

//自己实现的和STL标准有些出入,整形数组为例
using namespace std;

//向下调整
void Judge_down(vector<int>& arr, int parent, int size)
{
    int child = parent*2+1;

    while(child < size)
    {
        if(child + 1 < size && arr[child] < arr[child+1])
            child += 1;
        if(arr[parent] < arr[child])
        {
            swap(arr[parent], arr[child]);
            parent = child;
            child = child*2+1;
        }
        else
        {
            break;
        }
    }
}

//建堆
void Make_heap(vector<int>& arr)
{
    for(int i = (arr.size()-1)/2; i >= 0; --i)
    {
        Judge_down(arr, i, arr.size());
    }
}

//添加元素向上调整
void  Push_heap(vector<int> arr)
{
    int size = arr.size();
    int parent = (size - 1)/2;
    int child = size - 1;
    while(parent >= 0)
    {
        if(arr[parent] < arr[child])
        {
            swap(arr[parent],arr[child]);
            child = parent;
            parent = (child-1)/2;
        }
        else
        {
            break;
        }
    }
}


//删除堆顶元素
void Pop_heap(vector<int>& arr, int& size)
{
    //规则:将堆顶元素和最后一个元素交换,然后向下调整
    swap(arr[size - 1],arr[0]);
    Judge_down(arr, 0, --size);
}

void Sort_heap(vector<int>& arr)
{
    int size = arr.size();

    for(int i = 0; i <  arr.size(); ++i)
    {
        Pop_heap(arr, size);
    }
}

int main()
{
    int arr[] = {2,5,6,334,77,8};
    vector<int> v(arr, arr+6);
    Make_heap(v);
    v.push_back(99);
    Push_heap(v);
    Sort_heap(v);

    for(int i = 0;  i < v.size(); ++i)
    {
        cout<" ";
    }
    cout<"pause");
    return 0;
}

虽然堆在STL中是以算法的形式呈现的,但是STL还是提供了一个容器,优先级队列priority_queue; priority _queue既不提供遍历也不提供迭代器,底层采用堆算法;

下面测试一个实例:

#include
#include
#include

using namespace std;

int main()
{
    int arr[] = {1,2,34,67,3,24,23};
    priority_queue<int> q(arr,arr+7);

    while(!q.empty())
    {
        cout<" ";
        q.pop();
    }
    cout<return 0;
}

你可能感兴趣的:(数据结构)