[NJUPSOJ]堆

discription:
实现一个最小堆, 支持以下操作:
+x: 添加一个数字 x, 保证 0≤x≤100.
-: 删除堆里最小数字. 如果堆为空, 则什么也不干.
?: 输出堆里最小数字. 如果堆为空, 则输出 Error.
solution:
一道裸的优先队列, 正好拿来练手~
参考<<算法导论>>
code:

#include<cstdio>
struct priority_queue {
private:
	int Size;
	int q[114514];
	inline int left(const int& i) { return i << 1; }
	inline int right(const int& i) { return (i << 1) + 1; }
	inline int parent(const int& i) { return i >> 1; }
	inline void swap(int& x, int& y) { int t = x; x = y, y = t; }
	inline void min_heapify(const int& i) {
		int l = left(i), r = right(i), mini = i;
		if (l <= Size && q[l] < q[mini])mini = l;
		if (r <= Size && q[r] < q[mini])mini = r;
		if (mini != i) {
			swap(q[mini], q[i]);
			min_heapify(mini);
		}
	}
public:
	priority_queue() :Size(0){}
	inline void insert(const int& x) {
		int i = ++Size;
		q[i] = x;
		while (i > 1 && q[i] < q[parent(i)]) {
			swap(q[i], q[parent(i)]);
			i = parent(i);
		}
	}
	inline int top() { return q[1]; }
	inline void pop() {
		if (!Size)return;
		int i = Size--;
		swap(q[1], q[i]);
		min_heapify(1);
	}
	inline bool empty() { return !Size; }
};
inline int read() {
	int ch = getchar(), tot = 0;
	bool f = 0;
	while (ch < '0' || ch>'9') { if (ch == '-')f = 1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { tot = (tot << 1) + (tot << 3) + ch - '0', ch = getchar(); }
	return f ? -tot : tot;
}
int main() {
	priority_queue dwt;
	int n = read();
	while (n--) {
		int op = getchar();
		switch (op) {
		case '?': dwt.empty() ? printf("Error.\n") : printf("%d\n", dwt.top()); getchar(); break;
		case '+': dwt.insert(read()); break;
		default:  dwt.pop(); getchar(); break;
		}
	}
}

UPD更改了swap函数的实现: 如果用异或, 若 &x==&y, 经过 x^=y, x与y均置0.

posted @ 2021-02-11 11:16  _dwt  阅读(38)  评论(0)    收藏  举报