2-D搜索树

2-D搜索树

Description

根据给定的输入数据建立并维护一棵2-D搜索树,依次给出m条记录,每条记录包含Key1和Key2两个值,按顺序依次将这些记录插入2-D搜索树中,在给出m条记录的过程中,无规律地穿插有n条查询指令,包含Low1、High1、Low2和High2四个值,遇到查询指令时,搜索并输出到目前为止2-D搜索树中满足Low1<=Key1<=High1且Low2<=Key2<=High2的记录总数(只需输出数量,无需输出每条记录,因此本题与每个结点的value值无关,无需提供value值)。

Input Description

输入数据有(m+n+1)行,第一行有两个数m和n,分别表示插入结点总数和查询总次数。之后有m行插入指令和n行查询指令,二者无规律穿插在一起。插入指令以”0”开头,各数以空格隔开,格式为:0 Key1 Key2,表示向2-D搜索树中插入含有Key1和Key2的一条记录;查询指令以”1”开头,以空格隔开,格式为:1 Low1 High1 Low2 High2,表示查询到目前为止这棵树中满足Low1<=Key1<=High1且Low2<=Key2<=High2的记录总数,并逐行输出。

以上输入的所有数据均为int类型。其中0小于m小于100k,0小于n小于100k,Key1和Key2以及查询区间边界则可以为int范围内任意整数。

Input Sample

7 2
0 7 1
0 4 3
0 2 9
0 6 6
1 2 8 3 7
0 -1 5
0 6 3
0 5 3
1 1 6 2 3

Output Sample

2
3

Hint

  1. 参照二叉搜索树的实现,每个结点改为两个key值,并按照奇数层和偶数层来决定根据key1还是key2分叉(根结点为第1层,即奇数层)。可以在每个结点增加变量layer,用来判断此结点位于奇数层还是偶数层。

  2. 如何得到符合查询条件的记录个数?这与遍历整个二叉树有何区别?与在二叉搜索树中查找某个特定值又有何区别?请尽量采用高效的做法。

Idea

每添加一个结点相当于把xy平面分成两块,越分越小。最后求一个矩形框中点的个数。

Code

#include<iostream>
using namespace std;
struct Node{
    int key1,key2;
    int layer;
    Node *lc,*rc;
};
void Insert(Node *&BT,int item1,int item2,int Layer){
    if(BT==NULL){
        Node *p=new Node;
        p->key1=item1;
        p->key2=item2;
        p->layer=Layer;
        p->lc=p->rc=NULL;
        BT=p;
    }
    else if(Layer %2==1){
        if(item1 <= BT->key1)
            Insert(BT->lc,item1,item2,Layer+1);
        else
            Insert(BT->rc,item1,item2,Layer+1);
    }
    else if(Layer %2==0){
        if(item2 <= BT->key2)
            Insert(BT->lc,item1,item2,Layer+1);
        else
            Insert(BT->rc,item1,item2,Layer+1);
    }
}
void preOrder(Node *BT){
    if(BT!=NULL){
        cout<<BT->key1<<","<<BT->key2<<" ";
        preOrder(BT->lc);
        preOrder(BT->rc);
    }
}
int Seek(Node *BT,int low1,int high1,int low2,int high2){
    int count=0;
    if(BT==NULL)
        return 0;
    else{
        if(BT->layer %2==1){
            if(BT->key1 > high1)
                count+=Seek(BT->lc,low1,high1,low2,high2);
            else if(BT->key1 < low1)
                count+=Seek(BT->rc,low1,high1,low2,high2);
            else if(BT->key2 >= low2 && BT->key2 <=high2){
                count++;
                count+=Seek(BT->lc,low1,high1,low2,high2);
                count+=Seek(BT->rc,low1,high1,low2,high2);
            }
            else{
                count+=Seek(BT->lc,low1,high1,low2,high2);
                count+=Seek(BT->rc,low1,high1,low2,high2);
            }
        }
        if(BT->layer %2==0){
            if(BT->key2 > high2)
                count+=Seek(BT->lc,low1,high1,low2,high2);
            else if(BT->key2 < low2)
                count+=Seek(BT->rc,low1,high1,low2,high2);
            else if(BT->key1 >=low1 && BT->key1 <=high1){
                count++;
                count+=Seek(BT->lc,low1,high1,low2,high2);
                count+=Seek(BT->rc,low1,high1,low2,high2);
            }
            else{
                count+=Seek(BT->lc,low1,high1,low2,high2);
                count+=Seek(BT->rc,low1,high1,low2,high2);
            }
        }
    }
    return count;
}
int main(){
    int m,n;
    cin>>m>>n;
    int input[4];
    int *output=new int[n];
    int k=0;
    Node *BT=NULL;
    for(int i=0;i<m+n;i++){
        int flag;
        cin>>flag;
        if(flag==0){
            cin>>input[0]>>input[1];
            Insert(BT,input[0],input[1],1);
        }
        else if(flag==1){
            for(int j=0;j<4;j++)
                cin>>input[j];
            output[k]=Seek(BT,input[0],input[1],input[2],
                      input[3]);
            k++;
        }
    }
    for(int i=0;i<n;i++)
        cout<<output[i]<<endl;
    delete[] output;

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值