之前学习了一些堆、优先队列的知识点,在此做一个小总结。
堆(Heap)
堆(Heap)是一种特殊的完全二叉树数据结构,具有以下重要特性:
结构特性
堆是一棵完全二叉树,即除了最后一层外,其他层都是满的,且最后一层的节点都从左到右连续排列,这种结构特性使得堆可以用数组高效表示,不需要指针连接。
对于数组中位置i的节点(以1为数组起始点):
父节点位置:i/2
左子节点位置:2*i
右子节点位置:2*i+1
堆序特性
大根堆:每个节点的值都大于或等于其子节点的值(根节点最大)
小根堆:每个节点的值都小于或等于其子节点的值(根节点最小)
基本操作
插入:
- 将新元素添加到堆的末尾
- 执行向上调整操作,与父节点比较并交换,直到满足堆性质
删除根节点:
- 将根节点与最后一个节点交换
- 删除最后一个节点
- 对新的根节点执行向下调整操作,与子节点比较并交换,直到满足堆性质
建堆:
- 将无序数组构建成堆
- 从最后一个非叶子节点开始,向前逐个执行向下调整操作
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中的优先队列会按照从大到小的顺序排列元素(即大根堆实现)。
优先队列一般有以下几个常用操作:
- priority_queue <int> q:新建一个保存 int 型变量的优先队列q,默认是大根堆。
- priority_queue <int, vector <int> , greater <int>>g:新建一个小根堆。
- q.top():优先队列查询最大值(或者是最小值)。
- q.pop():将最大值(最小值)弹出队列。
- q.push(x):将x加入优先队列。
- q.empty():判断是否为空。
- q.size():获取大小。
当然,优先队列通常需要自定义比较规则,可以通过重载运算符来实现,在这里使用结构体内友元函数来进行重载。
friend bool operator<(const 结构体名& a,const 结构体名& b){return 优先级;
}//该重载在结构体内
如果大家有其他想法的,可以补充。