「编程之美扩展问题2.5」实时排名的树形分区设计

来源:互联网 发布:php编程题 编辑:程序博客网 时间:2024/05/16 07:11
树形分区设计 

均匀分区查询算法的失败是由于积分分布的非均匀性,那么我们自然就会想,能不能按二八定律,把score_range表设计为非均匀区间呢?比如,把低分区划密集一点,10分一个区间,然后逐渐变成100分,1000分,10000分 … 当然,这不失为一种方法,不过这种分法有一定的随意性,不容易把握好,而且整个系统的积分分布会随着使用而逐渐发生变化,最初的较好的分区方法可能会变得不适应未来的情况了。我们希望找到一种分区方法,既可以适应积分非均匀性,又可以适应系统积分分布的变化,这就是树形分区。

#include<iostream>using namespace std;struct TreeNode {    int fromScore;    int toScore;    int count;    TreeNode *left, *right;    TreeNode(int from, int to, int c = 0): fromScore(from), toScore(to), count(c), left(NULL), right(NULL){}};TreeNode* createTree(TreeNode *&root, int from, int to){    if(from > to) return NULL;    root = new TreeNode(from, to);    if(from == to) return root;    int mid = (from & to) + ((from ^ to) >> 1);    root->left = createTree(root->left, from, mid);    root->right = createTree(root->right, mid+1, to);    return root;}void insertNewScore(TreeNode *root, int score){    if(root == NULL) return;    if(score >= root->fromScore && score <= root->toScore)        root->count++;    int mid = (root->fromScore & root->toScore) + ((root->fromScore ^ root->toScore) >> 1);    if(score <= mid) insertNewScore(root->left, score);    else insertNewScore(root->right, score);}void deleteOldScore(TreeNode *root, int score){    if(root == NULL) return;    if(score >= root->fromScore && score <= root->toScore)         root->count--;    int mid = (root->fromScore & root->toScore) + ((root->fromScore ^ root->toScore) >> 1);     if(score <= mid) deleteOldScore(root->left, score);    else deleteOldScore(root->right, score);}void changeScore(TreeNode *root, int oldScore, int newScore){    deleteOldScore(root, oldScore);    insertNewScore(root, newScore);}void getRank(TreeNode *root, int score, int &rank){    if(root == NULL) return;    int mid = (root->fromScore & root->toScore) + ((root->fromScore ^ root->toScore) >> 1);     if(score > mid) getRank(root->right, score, rank);    else if(root->right)    {        rank += root->right->count;        getRank(root->left, score, rank);    }}int getRank(TreeNode *root, int score){    int rank = 1;    getRank(root, score, rank);    return rank;}void print(TreeNode *root){    if(root != NULL)    {        print(root->left);        cout<<root->fromScore <<" "<<root->toScore<<" "<<root->count<<endl;        print(root->right);    }}int main(){    TreeNode *root = NULL;    createTree(root, 1, 10);    int score[10] = {        1, 3, 5, 6, 2, 4, 3, 1, 7, 7    };    for(int i = 0; i < 10; ++i)        insertNewScore(root, score[i]);    cout<<"Rank is as follows:"<<endl;    print(root);    cout<<"Rank of score=5"<<endl;    cout<<getRank(root, 5)<<endl;    cout<<"Alter the score"<<endl;    changeScore(root, 2, 4);    print(root);    cout<<getRank(root, 3)<<endl;    return 0;}


0 0