本题应该挺经典的,因为可以使用好多方法过,适合训练多种高级数据结构和算法。
这里使用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()
{
}
};