【STL】堆

来源:互联网 发布:西瓜影音 mac版本 编辑:程序博客网 时间:2024/05/22 14:25

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


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

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

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

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

#include <algorithm>#include <vector>#include <iostream>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<<v[0]<<endl;    v.push_back(99);    push_heap(v.begin(), v.end());    cout<<v[0]<<endl;                //新加入一个99    sort_heap(v.begin(), v.end());   //堆排序    for(int i = 0; i < v.size(); ++i)    {        cout<<v[i]<<" ";    }    cout<<endl;    make_heap(v.begin(), v.end());    pop_heap(v.begin(), v.end());    cout<<v[0]<<endl;                 //删除堆顶    return 0;}

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

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

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

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

//实现堆和堆排序#include <iostream>#include <vector>//自己实现的和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<<v[i]<<" ";    }    cout<<endl;    system("pause");    return 0;}

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

下面测试一个实例:

#include<iostream>#include<algorithm>#include<queue>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.top()<<" ";        q.pop();    }    cout<<endl;    return 0;}
原创粉丝点击