扩充的数据结构-区间树interval-tree

(1)区间树所存的value为一个区间interval,其key值为interval的low值(即左值,由于树有左右节点,interval由low,high决定,避免混淆)

(2)区间树还储存某节点 x 的所有子节点中最大值m,即m = m[x], or m = m[x->left], or m = m[x->right.

m所带来的modifier操作的修改:

  1. 旋转操作:
    pnode left_rotate(pnode &x){
        pnode y = x->right;
        if(y->left != nil){
            x->right = y->left;
            y->left->p = x;
        }
        else
            x->right = nil;
    
        y->p = x->p;
        if(x->p != nil){
            if(x == x->p->left)
                x->p->left = y;
            else
                x->p->right = y;
        }
    
        y->left = x;
        x->p = y;
    
        int max = x->m;     //注意:旋转操作会使m的值改变, depends on their children's m
        if(x->right->m > max)
            max = x->right->m;
        x->m = max;
    
        max = y->m;
        if(y->left->m > max)
            max = y->left->m;
        y->m = max;
    
        return x;
    }

  2. 插入操作:
    void interval_insert(pnode &root, pnode z){
        tree_insert(root, z);
        pnode y = z;
        while(y != nil){    //注意:插入一个节点后,其父节点所有m值都需要重新确定,因为interval的右边界不定,时间为O(h)
            int max = y->m;     //h为插入node位置到root的path高度。(注意:树中某node的高度指该node到leave的path,注意与之区别)
            if(y->left != nil && y->left->m > max)
                max = y->left->m;
            if(y->right != nil && y->right->m > max)
                max = y->right->m;
            y->m = max;
            y = y->p;
        }
        z->color = 0;
        if(z->p == nil)
            z->color = 1;
        if(z->p->p != nil)
            interval_insert_fixup(z);
    }

  3. 删除操作:(待完成
测试:
void test(){
    pnode x = nil;

    pnode z = (pnode)malloc(sizeof(node)*6);

    z->interval = pair<int,int>(17,19); initial_node(z);
    interval_insert(x, z);

    (z+1)->interval = pair<int,int>(5,11); initial_node(z+1);
    interval_insert(x, z+1);

    (z+2)->interval = pair<int,int>(21,23); initial_node(z+2);
    interval_insert(x, z+2);

    (z+3)->interval = pair<int,int>(4,8); initial_node(z+3);
    interval_insert(x, z+3);


    (z+4)->interval = pair<int,int>(15,18); initial_node(z+4);
    interval_insert(x, z+4);

    (z+5)->interval = pair<int,int>(7,10); initial_node(z+5);
    interval_insert(x, z+5);

    pnode r = find_root(x);
    inorder_walk(r);
}

结果:
4:1, m=8;   5:0, m=18;   7:0, m=10;   15:1, m=18;   17:1, m=23;   21:1, m=23;   hello

阅读更多

没有更多推荐了,返回首页