实现一个map模版,能够实现以下的功能:
1.能在o(lgn)时间内,实现按key 值的添加,删除,查找。
2.能在o(lgn)时间内,实现按value 值排名的增删查
代码如下:
#include<iostream>
#include<string>
using namespace std;
//∂®“Â∫Ï∫⁄÷µ
const int RED =1;
const int BLACK =0;
template<typename K,typename V>
struct K_Value
{
K_Value():first(K()),second(V()){}
K_Value(const K &k,const V &v):first(k),second(v){}
K first; //÷∏œÚπÿº¸◊÷
V second; //÷∏œÚ÷µ
};
//∂®“ ˜Ω⁄µ„
template<typename T,typename V>
struct RBNode{
RBNode():left(NULL),right(NULL),parent(NULL),key(T()),value(V()),color(RED),l_child_nums(0),r_child_nums(0){}
RBNode(const T &v1,const V& v2):left(NULL),right(NULL),parent(NULL),key(v1),value(v2),color(RED),l_child_nums(0),r_child_nums(0){}
T key;
V value;
RBNode * left;
RBNode * right;
int color;
RBNode * parent;
int l_child_nums; //±»µ±«∞Ω⁄µ„–°µƒ∫¢◊”∏ˆ ˝
int r_child_nums; //±»µ±«∞Ω⁄µ„¥Ûµƒ∫¢◊”Ω⁄µ„∏ˆ ˝
};
//∂®“ƒ£∞Â
template <typename T,typename V> class Find_Map{
public:
Find_Map()
{
Nil = new RBNode<T,V>;
Nil->parent = Nil;
Nil->color = BLACK;
//Nil->key = NULL;
Nil->l_child_nums = 0;
Nil->r_child_nums = 0;
Nil->left = Nil;
Nil->right = Nil;
root = Nil;
}
//Œˆππ∫Ø ˝
~Find_Map()
{
delete Nil;
Nil = NULL;
root = NULL;
}
void RB_Create( K_Value<T,V> a[],int length ); //¥¥Ω®∫Ï∫⁄ ˜
void Delete(const T &key); //∞¥÷µ…æ≥˝
void Insert(const K_Value<T,V> &key); //∞¥÷µÃ̺”
K_Value<T,V> Search(const T &v1); //∞¥key≤È’“
K_Value<T,V> RankSearch(int rank); //∞¥≈≈√˚≤È’“
private:
RBNode<T,V> * TreeSuccessor(RBNode<T,V> * x);
void InsertReBalance(RBNode<T,V> * node); //≤»Î∫ÛΩ´ ˜≈™≥…∆Ω∫‚ ˜
void DeleteReBalance(RBNode<T,V> * node); //…æ≥˝∫ÛΩ´ ˜≈™≥…∆Ω∫‚ ˜
void _rotate_left(RBNode<T,V> * node); //◊Û–˝≤Ÿ◊˜
void _rotate_right(RBNode<T,V> * node); //”“–˝≤Ÿ◊˜
RBNode<T,V> * root;
RBNode<T,V> * Nil; //…Ë÷√…⁄±¯
};
//∞¥÷µ≤È’“
template<typename T,typename V>
K_Value<T,V> Find_Map<T,V>:: Search(const T& value)
{
//∏˘æ›typeµƒ¿‡–Õæˆ∂® «‘ˆº”ªπ «…æ≥˝ªÚ’fl≤ª∂Ø
RBNode<T,V> * p = root;
while(p != Nil && p->key != value)
{
if(p->key == value)
{
return K_Value<T,V>(p->key,p->value);
break;
}
//œÚ◊Û≤È’“
elseif(p->key < value)
{
p = p->right;
}
//œÚ”“≤È’“
else
{
p = p->left;
}
}
if(p->key == value)
{
return K_Value<T,V>(p->key,p->value);
}
return K_Value<T,V>();
}
// µœ÷∞¥≈≈√˚≤È’“
template<typename T,typename V>
K_Value<T,V> Find_Map<T,V>::RankSearch(int rank)
{
RBNode<T,V> * p = root;
int cur_rank; //±Ì æµ±«∞Ω⁄µ„µƒ≈≈√˚
//≤ª∫œ∑®––Œ™
if(rank <=0 )
{
}
//≥ı ºªØµ±«∞Ω⁄µ„≈≈√˚«Èøˆ
cur_rank = root->l_child_nums+1;
while(p)
{
//’“µΩ¡À≈≈√˚µƒ÷µ
if(rank == cur_rank)
{
return K_Value<T,V>(p->key,p->value);
}
//–Ë“™œÚ”“≤È’“
elseif(cur_rank < rank)
{
p = p->right;
cur_rank = cur_rank + p->l_child_nums +1;
}
//–Ë“™œÚ◊Û≤È’“
else
{
p = p->left;
cur_rank = cur_rank - p->r_child_nums -1;
}
}
return K_Value<T,V>();
}
//◊Û–˝≤Ÿ◊˜
template<typename T,typename V>
void Find_Map<T,V>::_rotate_left(RBNode<T,V> * x)
{
RBNode<T,V> * y = x->right;
//Ωªªª¡Ω∏ˆµƒΩ⁄µ„÷µ
int temp = y->l_child_nums;
y->l_child_nums = x->l_child_nums +y->l_child_nums +1;
x->r_child_nums = temp;
//xµƒ”“Ω⁄µ„Œ™yµƒ◊ÛΩ⁄µ„
x->right = y->left;
if(y->left != Nil)//»Áπ˚yµƒ◊ÛΩ⁄µ„¥Ê‘⁄£¨∆‰∏∏Ω⁄µ„Œ™y
y->left->parent = x;
y->parent = x->parent;
if ( x->parent == Nil )
{
root = y;
}
elseif ( x == x->parent->left )
{
x->parent->left = y;
}
else
{
x->parent->right = y;
}
//yµƒ◊Û◊”Ω⁄µ„Œ™x
y->left = x;
//xµƒ∏∏Ω⁄µ„Œ™y
x->parent = y;
}
//”“–˝≤Ÿ◊˜
template<typename T,typename V>
void Find_Map<T,V>::_rotate_right(RBNode<T,V> *x)
{
RBNode<T,V> *y = x->left;
//Ωªªª¡Ω∏ˆµƒΩ⁄µ„÷µ
int temp = y->r_child_nums;
y->r_child_nums = x->r_child_nums + 1 + y->r_child_nums;
x->l_child_nums = temp;
x->left = y->right;
if(y->right != Nil)
y->right->parent = x;
y->parent = x->parent;
if ( x->parent == Nil )
{
root = y;
}
elseif ( x == x->parent->left )
{
x->parent->left = y;
}
else
{
x->parent->right = y;
}
y->right = x;
x->parent = y;
}
//‘ˆº”“ª∏ˆΩ⁄µ„
template<typename T,typename V>
void Find_Map<T,V>::Insert(const K_Value<T,V>&key)
{
RBNode<T,V> * y = Nil;
RBNode<T,V> * x = root;
//…˙≥…“ª∏ˆ–¬µƒΩ⁄µ„
RBNode<T,V> * newNode = new RBNode<T,V>(key.first,key.second);
//Ω´À˘”–÷∏’Î÷∏œÚ…⁄±¯
newNode->parent = Nil;
newNode->left = Nil;
newNode->right = Nil;
while(x != Nil)
{
y = x;
if(newNode->key < x->key)
{
x->l_child_nums = x->l_child_nums +1;
x = x->left;
}
else
{
x->r_child_nums = x->r_child_nums +1;
x = x->right;
}
}
newNode->parent = y;
//»Áπ˚ ˜Œ™ø’µƒª∞£¨‘Ú¥ÀΩ⁄µ„Œ™ø’Ω⁄µ„
if(y ==Nil)
{
root = newNode;
root->color = BLACK;
}
//»Áπ˚Ω⁄µ„“—æ≠‘⁄∫Ï∫⁄ ˜÷–µƒª∞£¨≤ª‘ŸΩ¯––≤»Î
if(y->key == key.first)
{
return ;
}
if(y->key > key.first)
{
y->left = newNode;
}
else
{
y->right = newNode;
}
newNode->left = Nil;
newNode->right = Nil;
newNode->color = RED;
//∂‘∫Ï∫⁄ ˜Ω¯––µ˜’˚
InsertReBalance(newNode);
}
//Ω⁄µ„‘ˆº”∫Ûµƒ∆Ω∫‚≤Ÿ◊˜
template<typename T,typename V>
void Find_Map<T,V>::InsertReBalance(RBNode<T,V> * z)
{
while ( z->parent->color == RED )
{
if ( z->parent == z->parent->parent->left ) // z->parent->parent «∑ҥʑ⁄£ø£ø£ø
{
RBNode<T,V> *y = z->parent->parent->right;
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->right )
{
z = z->parent;
_rotate_left( z );
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
_rotate_right( z->parent->parent );
}
}
else
{
RBNode<T,V> *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;
_rotate_right( z );
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
_rotate_left( z->parent->parent );
}
}
}
root->color = BLACK;
}
//’“µΩºÃ»Œ’fl
template<typename T,typename V>
RBNode<T,V> * Find_Map<T,V>::TreeSuccessor(RBNode<T,V> * x)
{
if(x->right!=Nil)
{
RBNode<T,V> * p = x->right;
while(p->left!=Nil)
p = p->left;
return p;
}
RBNode<T,V> * y = x->parent;
while(y!=Nil && x == y->right)
{
x = y;
y = y->parent;
}
return y;
}
//…æ≥˝‘™Àÿ
template<typename T,typename V>
void Find_Map<T,V>::Delete(const T &key)
{
RBNode<T,V> * y = Nil;
RBNode<T,V> * x = Nil;
RBNode<T,V> * p = root;
//≤È’““™…æ≥˝µƒµ„
while(p!=Nil && p->key != key)
{
if(key < p->key)
{
p->l_child_nums = p->l_child_nums -1;
p = p->left;
}
else
{
p->r_child_nums = p->r_child_nums -1;
p = p->right;
}
}
//»Áπ˚∏√Ω⁄µ„”–»Œ“‚“ª∏ˆ∫¢◊”Ω⁄µ„Œ™ø’
if(p->left == Nil || p->right == Nil)
{
y = p; //º«◊°∏√µ„
}
//»Áπ˚”–¡Ω∏ˆ∑«ø’◊”Ω⁄µ„£¨’“µΩ∆‰∫ÛºÃΩ·µ„,»ª∫Û”√yº«◊°∆‰∫ÛºÃ
else
{
y = TreeSuccessor(p);
}
//º«xŒ™yµƒµ⁄“ª∏ˆ∑«ø’◊”Ω⁄µ„£¨»Áπ˚¡Ω∏ˆ
//∫¢◊”∂ºŒ™ø’µƒª∞‘Úº«xŒ™ø’
if( y->left !=Nil)
{
x = y->left;
y->l_child_nums-=1;
}
elseif(y->right!= Nil)
{
x = y->right;
y->r_child_nums -= 1;
}
x->parent = y->parent;
//»Áπ˚yŒ™∏˘Ω⁄µ„µƒª∞
if(y->parent == Nil)
{
root = x;
}
elseif(y == y->parent->left)
{
y->parent->left = x;
}
elseif(y == y->parent->right)
{
y->parent->right = x;
}
//»Áπ˚y”Îp≤ªÕ¨µƒª∞£¨Ω´p÷µøΩ±¥µΩy
if(y!=p)
{
p->key = y->key;
p->r_child_nums -= 1;
}
//»Áπ˚…æ≥˝µƒΩ⁄µ„ «∫⁄…´µƒ£¨‘Úµ˜”√–fi’˝∑Ω∑®
if(y->color == BLACK)
{
//Ω¯––µ˜’˚
DeleteReBalance(x);
}
delete y; // Õ∑≈ƒ⁄¥Ê
}
//Ω⁄µ„…æ≥˝∫Ûª÷∏¥∫Ï∫⁄ ˜µƒ∆Ω∫‚
template<typename T,typename V>
void Find_Map<T,V>::DeleteReBalance(RBNode<T,V> * node)
{
while(node != root && node->color == BLACK)
{
//∑÷Àƒ÷÷«Èøˆøº¬«
if(node == node->parent->left)
{
RBNode<T,V> * w = node->parent->right;
if(w->color == RED)
{
node->parent->color = RED;
w->color = BLACK;
_rotate_left(node->parent);
w = node->parent->right;
}
if(w->left->color == BLACK && w->right->color == BLACK)
{
w->color = RED;
node = node->parent;
}
else
{
if(w->left->color == RED && w->right->color == BLACK)
{
w->color = RED;
w->left->color = BLACK;
_rotate_right(w);
w = node->parent->right;
}
w->color = node->parent->color;
node->parent->color = BLACK;
w->right->color = BLACK;
_rotate_left(node->parent);
node = root;
}
}
else
{
RBNode<T,V> * w = node->parent->left;
if(w->color == RED)
{
w->color = BLACK;
node->parent->color = RED;
_rotate_right(node->parent);
w = node->parent->left;
}
if(w->left->color == BLACK && w->right->color == BLACK)
{
w->color = RED;
node = node->parent;
}
else
{
if(w->left->color == BLACK)
{
w->color = RED;
w->right->color = BLACK;
_rotate_left(w);
w = node->parent->left;
}
w->color = node->parent->color;
node->parent->color = BLACK;
w->left->color = BLACK;
_rotate_right(node->parent);
node = root;
}
}
}
node->color = BLACK;
}
template<typename T,typename V>
void Find_Map<T,V>::RB_Create( K_Value<T,V> a[],int length )
{
for(int i =0; i!= length;++i)
{
Insert(a[i]);
}
}
int main()
{
//…˘√˜»›∆˜
Find_Map<int,int> ia;
//≤»Α™Àÿ
K_Value<int,int> a(30,1);
K_Value<int,int> b(40,2);
K_Value<int,int> c(50,2);
K_Value<int,int> d(20,2);
K_Value<int,int> e(35,2);
K_Value<int,int> f(10,2);
K_Value<int,int> g(11,2);
ia.Insert(a);
ia.Insert(b);
ia.Insert(c);
ia.Insert(d);
ia.Insert(e);
ia.Insert(f);
ia.Insert(g);
cout<<"µ±keyµƒ÷µŒ™int ±"<<endl;
cout<<"µ±«∞key÷µ≈≈√˚Œ™£∫10->11->20->30->35->40->50"<<endl;
cout<<endl;
//∞¥÷µ≤È’“
K_Value<int,int> iv = ia.Search(11);
cout<<"∞¥÷µ≤È’“11:"<<endl;
cout<<"key="<<iv.first<<",value="<<iv.second<<endl;
cout<<endl;
// µ—È∞¥≈≈√˚≤È’“
K_Value<int,int> id = ia.RankSearch(4);
cout<<"∞¥≈≈√˚≤È’“4:"<<endl;
cout<<"key="<<id.first<<",value="<<id.second<<endl;
cout<<endl;
//…æ≥˝‘™Àÿ
cout<<"∞¥÷µ…æ≥˝‘™Àÿ30"<<endl;
ia.Delete(20);
cout<<endl;
//…æ≥˝∫Û µ—È∞¥≈≈√˚≤È’“
K_Value<int,int> def = ia.RankSearch(4);
cout<<"…æ≥˝∫Û∞¥≈≈√˚≤È’“4:"<<endl;
cout<<"key="<<def.first<<",value="<<def.second<<endl;
cout<<endl;
//»›∆˜key÷µŒ™◊÷∑˚¥Æ ±
Find_Map<string,int> st;
K_Value<string,int> sa("acs",1);
K_Value<string,int> sb("bgf",2);
K_Value<string,int> sc("fes",3);
K_Value<string,int> sd("tfs",4);
K_Value<string,int> se("tfg",5);
st.Insert(sa);
st.Insert(sb);
st.Insert(sc);
st.Insert(sd);
st.Insert(se);
cout<<"µ±keyµƒ÷µŒ™◊÷∑˚¥Æ ±"<<endl;
cout<<"µ±«∞◊÷∑˚¥Æ≈≈√˚Œ™£∫acs->bgf->fes->tfg->tfs"<<endl;
cout<<endl;
//∞¥÷µ≤È’“
K_Value<string,int> it = st.Search("acs");
cout<<"∞¥÷µ≤È’“acs"<<endl;
cout<<"key="<<it.first<<",value="<<it.second<<endl;
cout<<endl;
//∞¥≈≈√˚≤È’“
K_Value<string,int> ir = st.RankSearch(3);
cout<<"∞¥≈≈√˚≤È’“3"<<endl;
cout<<"key="<<ir.first<<",value="<<ir.second<<endl;
cout<<endl;
}