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