c++ 数据结构-堆、优先队列 小总结

之前学习了一些堆、优先队列的知识点,在此做一个小总结。

堆(Heap)

堆(Heap)是一种特殊的完全二叉树数据结构,具有以下重要特性:

结构特性

堆是一棵完全二叉树,即除了最后一层外,其他层都是满的,且最后一层的节点都从左到右连续排列,这种结构特性使得堆可以用数组高效表示,不需要指针连接。

对于数组中位置i的节点(以1为数组起始点):

父节点位置:i/2

左子节点位置:2*i

右子节点位置:2*i+1

堆序特性

大根堆:每个节点的值都大于或等于其子节点的值(根节点最大)

小根堆:每个节点的值都小于或等于其子节点的值(根节点最小)

基本操作
  • 插入:

    • 将新元素添加到堆的末尾
    • 执行向上调整操作,与父节点比较并交换,直到满足堆性质
  • 删除根节点:

    • 将根节点与最后一个节点交换
    • 删除最后一个节点
    • 对新的根节点执行向下调整操作,与子节点比较并交换,直到满足堆性质
  • 建堆:

    • 将无序数组构建成堆
    • 从最后一个非叶子节点开始,向前逐个执行向下调整操作
cpp 复制代码
int n,a[1000010];
void heapup(int i){//向上调整
    while(i>1&&a[i]<a[i/2]){
        swap(a[i],a[i/2]);
        i/=2;
    }
    return;
}
void heapdown(int i){//向下调整
    while(2*i<=n){
        int child=2*i;
        if(child<n&&a[child+1]<a[child])child++;
        if(a[i]>a[child]){
            swap(a[i],a[child]);
            i=child;
        }else break;
    }
    return;
}
void add(int x){//插入
    a[++n]=x;
    heapup(n);
    return;
}
void delete_(){//删除
    swap(a[1],a[n--]);
    heapdown(1);
    return;
}
void heapsort(){//建堆以及堆排序
    for(int i=n/2;i>=1;i--)heapdown(i);
    for(int i=n;i>1;i--){
        swap(a[1],a[i]);
        heap(1,--n);
    }
}

优先队列

优先队列(Priority Queue)是C++标准模板库(STL)中的一个容器,它提供了队列的功能,但元素出队顺序不是先进先出,而是按照优先级顺序出队。默认情况下,STL中的优先队列会按照从大到小的顺序排列元素(即大根堆实现)。

优先队列一般有以下几个常用操作:

  1. priority_queue <int> q:新建一个保存 int 型变量的优先队列q,默认是大根堆。
  2. priority_queue <int, vector <int> , greater <int>>g:新建一个小根堆。
  3. q.top():优先队列查询最大值(或者是最小值)。
  4. q.pop():将最大值(最小值)弹出队列。
  5. q.push(x):将x加入优先队列。
  6. q.empty():判断是否为空。
  7. q.size():获取大小。

当然,优先队列通常需要自定义比较规则,可以通过重载运算符来实现,在这里使用结构体内友元函数来进行重载。

cpp 复制代码
friend bool operator<(const 结构体名& a,const 结构体名& b){
    return 优先级;
}//该重载在结构体内

如果大家有其他想法的,可以补充。