堆通常是一个可以被看做一棵树的数组对象,堆中某个结点的值总是不大于(小根堆)或不小于(大根堆)其父结点的值,在插入和取出元素的时候,能自动调整树的结构,继续维持堆的特性。
C++
C++中的堆是优先队列priority_queue,默认声明为大根堆。需要#include <queue>
priority_queue<int> s; // 声明堆,默认为大根堆
priority_queue<int, vector<int>, greater<int>>s;// 声明小根堆的方式
priority_queue<int, vector<int>, less<int>>s; // 声明大根堆,和第一行效果相同
s.push(5); // 加入元素
s.pop(); // 删除堆顶
int a = s.top(); // 返回堆顶元素
int l = s.size(); // 返回元素个数
bool flag = s.empty(); // 判断堆是否为空,空返回1,否则返回0
Java
Java中的堆是优先队列PriorityQueue,默认声明为小根堆。需要import java.util.PriorityQueue;
// 声明一个堆,默认为小根堆
PriorityQueue<Integer> heap = new PriorityQueue<>();
// 声明大根堆的方式一(需要import java.util.Comparator;)
PriorityQueue<Integer> heap = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
// 声明大根堆的方式二
PriorityQueue<Integer> heap = new PriorityQueue<>((o1, o2) -> {
return o2-o1;
});
int []arr = {7,2,28,8,1,99,33,3,22};
for(int a: arr)
heap.add(a); // 添加元素
heap.offer(15); // 添加元素
/* add与offer的区别在于:
对于有大小限制的堆,如果满了再插入元素,
前者会抛出异常,后者会返回false */
heap.remove(28); // 根据值移除元素
heap.clear(); // 清空整个堆
int sz = heap.size(); // 获取堆的元素个数
boolean flag = heap.contains(99); // 返回是否包含某个值
boolean flag2 = heap.isEmpty(); // 返回堆是否为空
int top = heap.peek(); // 获取堆顶的值(不删除)
int top2 = heap.poll(); // 获取堆顶的值(删除)
// 遍历堆
for (int i: heap){
System.out.println(i);
}
Python
Python中的堆相关的包是heapq,但是只实现了小根堆,如果要使用大根堆,可以在存入和取出时对元素取相反数来实现。
import heapq # 导入包
hp = [7,2,28,8,1,99,33,3,22]
heapq.heapify(hp) # 小根堆化
heapq.heappush(hp, 5) # 放元素入堆
top = hp[0] # 返回堆顶(不取出)
a = heapq.heappop(hp) # 取出堆顶
b = heapq.heappushpop(hp, 0) # 先push再pop(看函数名)
c = heapq.heapreplace(hp, 0) # 先pop再push
max3 = heapq.nlargest(3, hp) # 查询堆中最大的3个元素
min3 = heapq.nsmallest(3, hp) # 查询堆中最小的3个元素
print(len(hp)) # 获取堆的元素个数