对一种数据结构的扩张过程可分为四步骤:
1)选择基础数据结构
2)确定要在基础数据结构中添加哪些信息
3)验证可用基础数据结构上的基本修改操作来维护这些新添加的信息
4)设计新的操作
动态顺序统计在红黑树的基础上添加x.size域,满足:x.size = x.left.size+x.right.size+1,扩张的结构如下:
操作:
1)检索具有给定秩的元素
下面伪代码返回一个指向以x为根的子树中包含第i小关键字的节点指针
2)确定元素的秩
伪代码如下:
3)插入
插入操作会破坏红黑树的性质,因此分两阶段进行:
a.对有根至叶子节点的路径上遍历的每个节点x都要增加其x.size,新增加的节点的size为1.(维护size域的额外开销为:O(lgn))
b.旋转调整(次数最多2次)。size域的改变如下:
具体旋转更新如下:
4)删除
也分两阶段:
a.从树中移除欲删除的点y,更新子树size (从y上溯到根节点,该路径上的节点size递减)。(开销O(lgn))
b.旋转调整
完整代码如下:
#include<iostream> #include<iomanip> using namespace std; #define BLACK 0 #define RED 1 typedef struct OSTNode{ int key; int size; //addtional information bool color; OSTNode *parent; OSTNode *left; OSTNode *right; }OSTNode; typedef struct OSTree{ OSTNode *root; }OSTree; OSTNode NILL={-1,0,BLACK,NULL,NULL,NULL}; OSTNode *NIL=&NILL; //init sentinel NIL void OST_InorderWalk(OSTNode *x) { if(x!=NIL) { OST_InorderWalk(x->left); cout<<setw(3)<<x->key; if(x->color==1) cout<<" Red "<<x->size<<endl; else cout<<" Black "<<x->size<<endl; OST_InorderWalk(x->right); } } OSTNode *OST_Search(OSTNode *x,int key) { if(x->key == key || x==NIL) return x; if(key < x->key) OST_Search(x->left,key); else OST_Search(x->right,key); } OSTNode *OST_Minimum(OSTNode *x) { while(x->left != NIL) x=x->left; return x; } void Left_Rotate(OSTree *T,OSTNode *x) { OSTNode *y=x->right; //set y x->right=y->left; //turn y's left subtree into x's right subtree if(y->left!=NIL) y->left->parent=x; y->parent=x->parent; //link x's parent to y; if(x->parent == NIL) T->root=y; else if(x==x->parent->left) x->parent->left=y; else x->parent->right=y; y->left=x; //put x on y's left x->parent=y; y->size=x->size; //Maintaining the inforamtion x->size=x->left->size+x->right->size+1; //Maintaining the informaiton } void Right_Rotate(OSTree *T,OSTNode *x) { OSTNode *y=x->left; //set y x->left=y->right; //link x's left tree into y's right subtree; if(y->right !=NIL) y->right->parent=x; y->parent=x->parent; //link x's parent to y if(x->parent == NIL) T->root=y; else if(x == x->parent->left) x->parent->left=y; else x->parent->right=y; y->right=x; //put x on y's right x->parent=y; y->size=x->size; x->size=x->left->size+x->right->size+1; } void OST_InsertFixup(OSTree *T,OSTNode *z) { while(z->parent->color==RED) { if(z->parent == z->parent->parent->left) { OSTNode *y=z->parent->parent->right; if(y->color==RED) { z->parent->color=BLACK; //case 1 y->color=BLACK; //case 1 z->parent->parent->color=RED; //case 1 z=z->parent->parent; //case 1 } else { if(z==z->parent->right) { z=z->parent; //case 2 Left_Rotate(T,z); //case 2 } z->parent->color=BLACK; //case 3 z->parent->parent->color=RED; //case 3 Right_Rotate(T,z->parent->parent); //case 3 } } else {//a me as then clause with "right" and "left" exchanged OSTNode *y=z->parent->parent->left; if(y->color==RED) { z->parent->color==BLACK; y->color=BLACK; z->parent->parent->color=RED; z=z->parent->parent; } else { if(z==z->parent->left) { z=z->parent; Right_Rotate(T,z); } z->parent->color=BLACK; z->parent->parent->color=RED; Left_Rotate(T,z->parent->parent); } } } T->root->color=BLACK; //turn the root to BLACK } void OST_Insert(OSTree *T,int value) { OSTNode *z=new OSTNode(); z->key=value; z->size=1; //init size z->color =RED; z->parent=NIL; z->left=NIL; z->right=NIL; OSTNode *y=NIL; //y is the parent of x OSTNode *x=T->root; while(x != NIL) { x->size++; //increasing size when inserting y=x; if(z->key < x->key) x=x->left; else x=x->right; } z->parent=y; //link new node's parent node to y(y's child is NIL) if(y==NIL) T->root=z; else if(z->key < y->key) y->left=z; else y->right =z; OST_InsertFixup(T,z); } /*void OST_Transplant(OSTree *T,OSTNode *u,OSTNode *v) { if(u->parent==NIL) T->root=v; else if(u==u->parent->left) u->parent->left=v; else u->parent->right=v; v->parent=u->parent; } */ void OST_DeleteFixup(OSTree *T,OSTNode *x) { OSTNode *w; while(x!=T->root && x->color==BLACK) { if(x==x->parent->left) { w=x->parent->right; //set w to x's sibling if(w->color==RED) //case 1:x's sibling w is red { w->color=BLACK; x->parent->color=RED; Left_Rotate(T,x->parent); w=x->parent->right; } if(w->left->color==BLACK && w->right->color==BLACK) { //case 2:x's sibling w is black and both of w's children are black w->color=RED; x=x->parent; } else { if(w->right->color==BLACK) {//case 3:x's sibling w is black,w's left child is red, and w's right child is black w->left->color=BLACK; w->color=RED; Right_Rotate(T,w); w=x->parent->right; } w->color=x->parent->color; //case 4: x's sibling w is black,and w's right child is red x->parent->color=BLACK; //. w->right->color=BLACK; // . Left_Rotate(T,x->parent); // . x=T->root; //case 4 } } else {//Same as then clause with "right" and "left" exchanged w=x->parent->left; if(w->color==RED) { w->color=BLACK; x->parent->color=RED; Right_Rotate(T,x->parent); w=x->parent->left; } if(w->left->color==BLACK && w->right->color==BLACK) { w->color=RED; x=x->parent; } else { if(w->left->color==BLACK) { w->right->color=BLACK; w->color=RED; Left_Rotate(T,w); w=x->parent->left; } w->color=x->parent->color; x->parent->color=BLACK; w->left->color=BLACK; Right_Rotate(T,x->parent); x=T->root; } } } x->color=BLACK; } OSTNode *OST_Successor(OSTNode *x){ OSTNode *r = x; if(r->right != NIL) return OST_Minimum(r->right); OSTNode *y = r->parent; while(y != NIL && r == y->right){ r = y; y = y->parent; } return y; } void OST_Delete(OSTree *T,OSTNode *z) { OSTNode *x=NULL,*y=NULL,*g=NULL; if(z->left == NIL || z->right==NIL) y=z; else y=OST_Successor(z); g=y->parent; while(g!=NIL) //traverse a simple path from node y up to the root, { //decrementing the size attribute of each node on the path g->size--; g=g->parent; } if(y->left !=NIL) x=y->left; else x=y->right; x->parent=y->parent; if(y->parent==NIL) T->root=x; else if(y==y->parent->left) y->parent->left=x; else y->parent->right=x; if(y != z) z->key=y->key; if(y->color==BLACK) OST_DeleteFixup(T,x); } /*-----------------------------------------------------------------------*/ OSTNode *OST_Select(OSTNode *x,int i) {//return the node with ith smallest key in OST if( x== NIL) return x; int r=x->left->size+1; if( i==r) return x; else if(i < r) return OST_Select(x->left,i); else return OST_Select(x->right,i-r); } int OST_Rank(OSTree *T,OSTNode *x) { int r; OSTNode *y; r=x->left->size+1; y=x; while(y != T->root) { if(y == y->parent->right) r+=y->parent->left->size+1; y=y->parent; } return r; } /*-----------------------------------------------------------------------*/ int main() { int A[]={41,38,31,12,19,8,45}; int n=sizeof(A)/sizeof(int); cout<<"/*---------------Create Order-Statitics Tree-----------------*/"<<endl; OSTree *T=new OSTree(); T->root=NIL; for(int i=0;i<n;i++) OST_Insert(T,A[i]); cout<<"The Order-Statitics tree is:"<<endl; OST_InorderWalk(T->root); cout<<"The root of the OST is:"<<T->root->key<<endl; cout<<"/*-----------------------------------------------------------*/"<<endl; cout<<"/*------------Search ith smallest key in OST-----------------*/"<<endl; int ith_smallest; cout<<"Please input i:"; cin>>ith_smallest; OSTNode *ithNode=NIL; ithNode=OST_Select(T->root,ith_smallest); if(ithNode==NIL) cout<<"The OST doesn't exist smallest key."<<endl; else { cout<<"The ith smallest Node is: "; cout<<"Key:"<<ithNode->key<<" "; if(ithNode->color==1) cout<<"Color:Red "; else cout<<"Color-Black "; cout<<"Size:"<<ithNode->size<<endl; int rank=OST_Rank(T,ithNode); cout<<"This Node's Rank is:"<<rank<<endl; } cout<<"/*----------------------- OST Delete--------------------*/"<<endl; int dkey; cout<<"Please input the deleting key:"; cin>>dkey; OSTNode *dNode=NIL; dNode=OST_Search(T->root,dkey); if(dNode==NIL) cout<<"The deleting key doesn't eixst in the OST."<<endl; else { OST_Delete(T,dNode); cout<<"After deleting ,the OST is:"<<endl; OST_InorderWalk(T->root); cout<<"The root of OST is:"<<T->root->key<<endl; } cout<<"/*-----------------------------------------------------------*/"<<endl; return 0; } 运行结果: <img src="http://img.blog.csdn.net/20150716214323469" alt="" /> 【注:若有错误,请指正~~~】
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u010183397/article/details/46916973