二叉堆基本模板(正稿)

  • PS:前面没用markdown,粘上来的代码连缩进都没有,没法看。。。
  • 首先澄清一下优先队列和二叉堆之间的关系,这是基本的计算机科学理论知识;
  • 优先队列是一种抽象数据结构,它的概念只关心它具有什么功能,而不关心这些功能是如何实现的;
  • 优先队列最常用二叉堆实现;
  • 形象地说,我们有一台黑箱,上面写着”优先队列“四个字,它带有实现优先队列功能(插入值,取出最值)的出入口;而拆开黑箱,里面是用二叉堆搭建的;
  • 现在C++标准模板库容器除了双向链表(list)和并查集以外都允许在OI中使用,因而实现优先队列基本上不用手写,用priority_queue就可以了;
  • 除非是应付笔试阅读题,需要熟悉手写二叉堆;
  • priority_queue包含在头文件queue中;
  • priority_queue默认是大根堆,定义格式为priority_queue,其中T为基本数据类型或string(理论上来说其它通用容器也能这样搞,但实际不常用,如有需要改日另论);
  • 若需转为小根堆,需额外包含头文件vector,格式为priority_queue< T,vector,greater >;
  • 对于结构体,需要在结构体内重载<(小于号)运算符,代码如下:
#include
#include
using namespace std;
struct Node{
    int aa,bb;
    bool operator<(const Node &anth)const
    {
        if(aa==anth.aa) return bbelse return aa pqn;
int main()
{
    int n,i;
    Node tmpn;
    cin>>n;
    for(i=0;icin>>tmpn.aa>>tmpn.bb;
        pqn.push(tmpn);
    }
    while(!pqn.empty())
    {
        cout<' '<return 0;
}
  • 对于每一对输入的int型数,它以第一个数为第一关键字,第二个数为第二关键字降序排序;
  • 如果需要改成升序,把重载函数中的两个小于号改成大于号就行了;
  • 总之在重载函数中写成小于号的一律降序,写成大于号的一律升序;
  • 另有手写小根堆模板,应付初赛用:
#include
#include
using namespace std;
const int MAXN=1000;
int heap[MAXN+2];//利用完全化数组存储二叉树
int N=0;//堆尾标记
void heap_put(int nval)
{
    N++;//升起堆尾标记
    heap[N]=nval;//插入新堆尾
    int sonloc=N;//设置随当前堆尾值一同转移的动态标记sonloc
    while(sonloc>1)//当sonloc对应堆中实际存在的结点时
    {
        if(heap[sonloc/2]>heap[sonloc])//如果当前结点比它的亲结点小
        {
            swap(heap[sonloc/2],heap[sonloc]);//交换亲结点和子结点的值
            sonloc/=2;//将sonloc置到它原本的亲结点位置
        }
        else break;
    }
    return;
}
int heap_get()
{
    int tarval=heap[1];//取出堆头
    heap[1]=heap[N];//将原本的堆尾临时搁到堆头的位置
    N--;//降下堆尾标记
    int curloc=1;//设置随新堆头值一同转移的动态标记curloc
    while(2*curloc<=N)//当当前结点的左孩子是堆中实际存在的结点时
    {
        if(2*curloc+1>N||heap[2*curloc]2*curloc+1])//如果右孩子不存在,或左孩子是一个更优的选择
        {
            swap(heap[curloc],heap[2*curloc]);//交换亲结点和左子结点的值
            curloc*=2;//将curloc置到它原本的左子节点的位置
        }
        else
        {
            swap(heap[curloc],heap[2*curloc+1]);//交换亲结点和右子结点的值
            curloc=2*curloc+1;//将curloc置到它原本的右子结点的位置
        }
    }
    return tarval;//返回刚刚取出的堆头
}
int main()
{
    int n,tmpn;
    char oprt;
    cout<<"Please input the size of your original heap: ";
    cin>>n;
    cout<<"Please input the elements in your original heap:\n";
    int i;
    for(i=0;icin>>tmpn;
        heap_put(tmpn); 
    }
    cout<<"Please input your operation: ";
    cin>>oprt;
    if(oprt=='p')
    {
        cin>>tmpn;
        heap_put(tmpn);
        cout<<"The elements in the heap now are:\n";
        n=N;
        for(i=0;icout<' ';
    }
    if(oprt=='g') cout<<"The element you have got is: "<cout<return 0;
}

你可能感兴趣的:(优先队列与二叉堆,计算机科学,数据结构)