Poj Double Queue 3481 AVL解法

本题应该挺经典的,因为可以使用好多方法过,适合训练多种高级数据结构和算法。

这里使用AVL平衡二叉树的解法,时间还可以,大概300ms吧,内存很省188k,因为这里使用指针,没有浪费内存。

这里使用Geeks上面的AVL的做法,使用递归更新树,而不使用双亲指针,试了下使用双亲指针,真的好麻烦,要维护多一个指针,容易出错很多。

递归操作二叉树是非常优雅的。

而且不需要使用任何STL容器,非常原始,直接的解法,呵呵,可以控制任何一个细节,还是很好的。

#include <stdio.h>
#include <algorithm>
using std::max;

class DoubleQueue3481_2
{
	struct Node
	{
		int key, num;
		Node *left, *right;
		int h;
		Node(int k, int n) : key(k), num(n), left(NULL), right(NULL), h(1) {}
		~Node()
		{
			if (left) delete left;
			if (right) delete right;
		}
	};

	void updateHeight(Node *n)
	{
		n->h = max(getHeight(n->left), getHeight(n->right)) + 1;
	}

	int getHeight(Node *n)
	{
		if (!n) return 0;
		return n->h;
	}

	Node *leftRotate(Node *y)
	{
		Node *x = y->right;
		y->right = x->left;
		x->left = y;

		updateHeight(y);
		updateHeight(x);
		return x;
	}

	Node *rightRotate(Node *y)
	{
		Node *x = y->left;
		y->left = x->right;
		x->right = y;

		updateHeight(y);
		updateHeight(x);
		return x;
	}

	int getBalance(Node *n)
	{
		if (!n) return 0;
		return getHeight(n->left) - getHeight(n->right);
	}

	Node *balanceNode(Node *n)
	{
		if (!n) return n;

		updateHeight(n);

		int balance = getBalance(n);

		if (balance > 1 && getBalance(n->left) >= 0)
			return rightRotate(n);
		if (balance < -1 && getBalance(n->right) <= 0)
			return leftRotate(n);
		if (balance > 1 && getBalance(n->left) < 0)
		{
			n->left = leftRotate(n->left);
			return rightRotate(n);
		}
		if (balance < -1 && getBalance(n->right) > 0)
		{
			n->right = rightRotate(n->right);
			return leftRotate(n);
		}
		return n;
	}

	Node *insert(Node *n, int key, int num)
	{
		if (!n) return new Node(key, num);

		if (key < n->key) n->left = insert(n->left, key, num);
		else n->right = insert(n->right, key, num);

		return balanceNode(n);
	}

	Node *minValueNode(Node *n)
	{
		if (!n) return n;
		Node *cur = n;
		while (cur->left) cur = cur->left;
		return cur;
	}

	Node *maxValueNode(Node *n)
	{
		if (!n) return n;
		Node *cur = n;
		while (cur->right) cur = cur->right;
		return cur;
	}

	Node *delNode(Node *r, int key)
	{
		if (!r) return r;

		if (key < r->key) r->left = delNode(r->left, key);
		else if (r->key < key) r->right = delNode(r->right, key);
		else
		{
			if (!r->left || !r->right)
			{
				Node *t = r->left? r->left : r->right;
				if (!t)
				{
					t = r;
					r = NULL;
				}
				else *r = *t;//copy content, be careful about the *
				delete t;
				t = NULL;
			}
			else
			{
				//key step: get inorder successor
				Node *t = minValueNode(r->right);
				r->key = t->key;
				r->right = delNode(r->right, t->key);
			}
		}
		return balanceNode(r);
	}

	void preOrder(Node *root)
	{
		if(root != NULL)
		{
			preOrder(root->left);
			printf("%d ", root->key);
			preOrder(root->right);
		}
	}
public:
	DoubleQueue3481_2()
	{
		Node *root = NULL;
		int req = 0;
		while (scanf("%d", &req) != EOF)
		{
			if (0 == req) break;
			else if (1 == req)
			{
				int k, p;
				scanf("%d %d", &k, &p);
				root = insert(root, p, k);
			}
			else if (2 == req)
			{
				Node *maxNode = maxValueNode(root);
				if (!maxNode) printf("0\n");
				else printf("%d\n", maxNode->num);

				//写少了个root =
				if (maxNode) root = delNode(root, maxNode->key);
			}
			else if (3 == req)
			{
				Node *minNode = minValueNode(root);
				if (!minNode) printf("0\n");
				else printf("%d\n", minNode->num);
				if (minNode) root = delNode(root, minNode->key);
			}
		}
		if (root) delete root;
	}

	~DoubleQueue3481_2()
	{
	}
};

Poj Double Queue 3481 AVL解法

时间: 2024-08-03 18:07:56

Poj Double Queue 3481 AVL解法的相关文章

AVL树(模板题)—— POJ 3481 Double Queue

对应POJ题目:点击打开链接 Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11741   Accepted: 5335 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing env

poj 3841 Double Queue (AVL树入门)

1 /****************************************************************** 2 题目: Double Queue(poj 3481) 3 链接: http://poj.org/problem?id=3481 4 算法: avl树(入门) 5 *******************************************************************/ 6 #include<cstdio> 7 #inclu

POJ 题目3481 Double Queue(SBT ro map)

Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11824   Accepted: 5385 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provid

POJ 3481 Double Queue(Treap模板题)

Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15786   Accepted: 6998 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provid

跳跃表基础——POJ 3481 Double Queue

对应POJ 题目:点击打开链接 Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11768   Accepted: 5349 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing en

POJ - 3481 - Double Queue (STL)

Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11133   Accepted: 5056 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provid

POJ 3481 Double Queue(STL)

题意  模拟银行的排队系统  有三种操作  1-加入优先级为p 编号为k的人到队列  2-服务当前优先级最大的   3-服务当前优先级最小的  0-退出系统 能够用stl中的map   由于map本身就依据key的值排了序   相应2.3  我们仅仅须要输出最大或最小即可了并从map中删除该键值 #include<cstdio> #include<map> using namespace std; map<int, int> a; int main() { map<

POJ 3481 Double Queue 堆修改标记

Enemy Double Queue! 题目大意:维护一种数据结构,支持以下操作: 1.插入一个值 2.查询最大值并删除 3.查询最小值并删除 元素的值<=1000W 这数据结构一看就是堆...不过堆结构不能同时维护最大值和最小值,于是我们开两个堆,一个大根堆,一个小根堆 其中一堆删除时,另一堆也要删除相应元素 于是删除的话有两种方法 1.映射 1000W开数组映射妥妥MLE 于是我们在两个堆之间互相映射 不太好写 pair里开自己的指针会报错,于是只能开了void* 不过速度还是很可观的 #i

POJ 3481 Double Queue(set实现)

Double Queue The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provided by IBM Romania, and using modern information technologies. As usual, each client of the bank