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

来源:互联网 发布:js 数组最大值 编辑:程序博客网 时间:2024/05/16 15:29

(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

0 0