给出动态更新数据,实时问第K个大的数值是什么?
利用AVL数据结构做的一个统计数,比较高级的数据结构内容了。
不知道题目给出的数据值是否有重复,因为我下面的程序是可以处理出现数据重复的情况的。
其中的奥妙是增加了repeat的信息,可以知道出现了当前数组多少次。
主要是知道如何维护这些数据和如何查询,维护数据的函数是pushUp,查询函数是selectKth。
其他就是一般的AVL操作。个人觉得我的AVL写的还算蛮清晰的,有需要的参考一下。
#include <stdio.h>
inline int max(int a, int b) { return a > b? a : b; }
inline int min(int a, int b) { return a < b? a : b; }
struct Node
{
int key, h, size, repeat; //repeat for record the repeated key times
Node *left, *right;
explicit Node(int val = 0) : left(NULL), right(NULL),
key(val), repeat(1), h(1), size(1){}
};
inline int getHeight(Node *n)
{
if (!n) return 0;
return n->h;
}
inline int getSize(Node *n)
{
if (!n) return 0;
return n->size;
}
inline int getBalance(Node *n)
{
if (!n) return 0;
return getHeight(n->left) - getHeight(n->right);
}
inline void pushUp(Node *n)
{
if (!n) return ;
n->size = getSize(n->left) + getSize(n->right) + n->repeat;
n->h = max(getHeight(n->left), getHeight(n->right)) + 1;
}
inline Node *leftRotate(Node *x)
{
Node *y = x->right;
x->right = y->left;
y->left = x;
pushUp(x);
pushUp(y);
return y;
}
inline Node *rightRotate(Node *x)
{
Node *y = x->left;
x->left = y->right;
y->right = x;
pushUp(x);
pushUp(y);
return y;
}
inline Node *balanceNode(Node *n)
{
if (!n) return n;
int balance = getBalance(n);
if (balance > 1)
{
if (getBalance(n->left) < 0) n->left = leftRotate(n->left);
n = rightRotate(n);
}
else if (balance < -1)
{
if (getBalance(n->right) > 0) n->right = rightRotate(n->right);
n = leftRotate(n);
}
return n;
}
Node *insert(Node *rt, int val)
{
if (!rt) return new Node(val);
if (rt->key == val) rt->repeat++;
else if (rt->key < val) rt->left = insert(rt->left, val);
else rt->right = insert(rt->right, val);
pushUp(rt);
return balanceNode(rt);
}
int selectKth(Node *rt, int k)
{
int lSize = getSize(rt->left);
if (k <= lSize) return selectKth(rt->left, k);
else if (lSize + rt->repeat < k)
return selectKth(rt->right, k - lSize - rt->repeat);
return rt->key; // lSize < k <= lSize+rt->repeat
}
void deleteTree(Node *rt)
{
if (rt)
{
if (rt->left) deleteTree(rt->left);
if (rt->right) deleteTree(rt->right);
delete rt; rt = NULL;
}
}
int main()
{
int n, k, val;
char c;
while (scanf("%d %d", &n, &k) != EOF)
{
Node *tree = NULL;
for (int i = 0; i < n; i++)
{
getchar();// get rid of '\n'
c = getchar();
if ('I' == c)
{
scanf("%d", &val);
tree = insert(tree, val);
}
else
{
printf("%d\n", selectKth(tree, k));
}
}
deleteTree(tree);
}
return 0;
}