《算法导论》笔记(7) 区间树、B树

动态顺序统计。一种是红黑树结点储存附加子树的元素数size。一种是储存中序遍历的秩r。插入、删除时对附加属性的维护。相类似的扩展的红黑树附加属性f若仅依赖于x、x.left、x.right,还可能包括x.left.f与x.right.f,则插入删除时维护所有结点的属性f,不影响O(lg(n))渐近性能。

区间树。区间属性x.int,关键字x.int.low,构成红黑树,节点附加属性x.max=max(x.left.max, x.int.high, x.right.max)。

interval_insert(T, x){i=RB_insert(T, x); i.int=x.int;}
interval_search(T, x){i=RB_search(T, x); if(i.int==x.int) return i; else throw error;}
interval_delete(T, x){if(i=interval_search(T, x)) RB_delete(i); else throw error;}

B树。结点有n个key,有n+1个孩子。B+树卫星数据都储存在叶结点中,内部结点只有关键字和孩子指针。除根外每个结点都有t-1到2t-1个关键字。插入关键字到满叶结点需要将叶结点分裂为2,中间关键字提升标识新划分点。若父结点也满,则继续分裂并向上传播。插入过程中可能分裂根并增加树高度。删除操作分叶结点与内部结点,叶结点中的关键字直接删除,内部结点中的关键字分2种情况:1,前驱或后继的子结点元素数大于t-1则取一个代替k,若都只有t-1则合并子结点并删除k,2,从根开始搜索,经过的子结点小于t则与父结点、兄弟结点置换一个,兄弟结点都少于t则合并。

B_Tree_search(x, k){
 i=find_in(x, k);
 if(k==x.key[i]) return x.i;
 if(x.leaf) return null;
 else return B_Tree_search(x.i,k);
}

find_in(x, k){
 i=1; while(i<=x.n && k>=x.key[i]){i++;}
 return i; 
}

B_Tree_insert(x, k){
 r=T.root;
 if(r.n==2t-1) {s=new node(); T.root=s; s.child[1]=r; B_Tree_split_child(s,1);}
 B_Tree_insert_nonfull(s,k);
}

B_Tree_insert_nonfull(x, k){
 i=find_in(x, k);
 if(k==x.key[i]) return;
 if(x.leaf) x.insert(i,k); return;
 if(x.child[i].n==2*t-1) B_Tree_split_child(x, i); //向下搜索前保证子结点未满否则分裂
 if(k>x.key[i]) i++;
 return B_Tree_insert_nonfull(x.child[i], k);
}

B_Tree_split_child(x, i){
 x.insert_new_node(i);
 x.key[i]=x.child[i].key[t];
 x.child[i]=x.child[i].split(1, t-1);
 x.child[i+1]=x.child[i].split(t+1,2*t-1);
}

B_Tree_delete(x, k){
 r=T.root;
 if(r.n==1 && r.child[1].n==t-1 && r.child[2].n==t-1) B_Tree_cat(r,1);
 B_Tree_delete_nonempty(s,k);
}

B_Tree_delete_nonempty(x, k){
 i=find_in(x, k); 
 if(x.leaf && k==x.key[i]) {x.delete(i); return;} //叶中直接删
 elseif(!x.leaf && k==x.key[i]){  //内部结点删除并将下层提升一个
  if(x.child[i].n>t-1) {x.key[i]=x.child[i].key[x.child[i].n]; return B_Tree_delete_nonempty(x.child[i], x.child[i].key[x.child[i].n]);}
  elseif(x.child[i+1].n>t-1) {x.key[i]=x.child[i+1].key[1]; return B_Tree_delete_nonempty(x.child[i+1], x.child[i+1].key[1]);}
  else{B_Tree_cat(x,i); return B_Tree_delete_nonempty(x.child[i],k); }
 }
 elseif(!x.leaf && k!=x.key[i]){  //向下继续寻找则先保证子结点个数不少于t
  if(x.child[i].n<t && x.child[i+1].n>=t){
   x.child[i].add_key(x.key[i]); x.child[i].add_child(x.child[i].n+1,x.child[i+1].child[1]);
   x.key[i]=x.child[i+1].key[1];
   x.child[i+1].delete_key(1); x.child[i+1].delete_child(1);   
  }
  elseif(x.child[i].n<t && x.child[i+1].n<t){
   B_Tree_cat(x,i);
  }
  return B_Tree_delete_nonempty(x.child[i], k); 
 }
}

B_Tree_cat(x,i){
 x.child[i].key+=x.key[i]+x.child[i+1].key;
 x.child[i].child+=x.child[i+1].child;
 x.delete(key[i]);
}
    原文作者:B树
    原文地址: https://blog.csdn.net/nklofy/article/details/43528675
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注