priority_queue的底层实现及数组建堆。


注意:

1 如果要用到小顶堆,则一般要把模板的三个参数都带进去。 STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明小顶堆

#include 
#include 
 
using namespace std;
 
int main(){
    priority_queue, greater > q;
     
    for( int i= 0; i< 10; ++i ) q.push( rand() );
    while( !q.empty() ){
        cout << q.top() << endl;
        q.pop();
    }
     
    getchar();
    return 0;
}

2 为了指定第三个模板参数,我们必须将前两个参数都指明出来(这是C++语法规则).



stack与queue注意事项:

1 stack不允许有遍历行为,stack也不提供迭代器。SGI STL便以deque作为缺省情况下stack底部结构,称之为adapter(配接器)

2 除了deque之外,list也是双向开口的数据结构

3 queue与stack的情况类似,不提供迭代器,也可以以list作为底层容器,默认为deque


priority_queue的底层实现——heap


缺省情况下priority_queue优先级队列是利用一个max-heap最大堆完成,后者是一个以vector表现的完全二叉树。

“依权值高低自动递减排序”



priority_queue允许用户以任何次序将任何元素推入容器内,但取出时一定是从优先权最高(也即数值最高,最大堆)的元素开始取。

2 二叉堆,完全二叉树,(由数组实现,数组来存储所有节点,2*i+1,2*i+2,但是由于动态改变大小,所以不用array用vector)插入O(logN),删除O(logN)


本人亲自实现的堆排序过程:

#include 
#include 
#include 
using namespace std;

/*
调整堆:默认最大堆,每次调整结束后,堆顶即为最大值。
类似于:向上冒泡的过程。
*/
void maxheapfixdown(int a[], int i, int n){
    int tmp = a[i];
    int j = 2 * i + 1;
    while (j= 0; --i)
    {
        maxheapfixdown(a, i, n);//建堆,从末尾的第一个非叶节点,即i=(n-2)/2处开始。
    }
    for (int k = 1; k <= n - 1; ++k)//建堆时相当于完成了一次堆调整,还需要n-1次堆调整。
    {
        swap(a[0], a[n - k]);//上次调整完之后,把最大值放到末尾。
        maxheapfixdown(a, 0, n - k);
    }

}

#define N 500

int main()
{

    srand((unsigned)time(NULL));
    int a[N];
    for (int i = 0; i < N; i++)
    {
        a[i] = rand() % (N + 1);
    }

    for (int i = 0; i < N; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;
    cout << "********************" << endl;
    heap_sort(a, N);

    for (int i = 0; i < N; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;

    system("pause");


    return 0;
}


STL heap包括:

1 push_heap算法:新元素插入在底层的vector的end()处。向上回溯

2 pop_heap算法:把堆顶元素和数值末尾元素调换,向下回溯。

3 sort_heap算法:持续对整个heap做pop_heap操作,每次将操作范围从后向前缩减一个元素。执行过后,原来的heap不再是个合法的heap了。

4 meak_heap算法:找出第一个需要重排的子树头部(n-2)/2,从当前位置向根节点回溯。




你可能感兴趣的:(STL)