寫一個自己想要的“set”,想實現什麼功能直接在裏面添加。STL雖然把set封裝的很好,很強大,易於擴展,但是正由於兼容性很好,封裝太多層,犧牲了很多性能。下面是我的測試結果
void test(int num) {
time_t rawtime;
time(&rawtime);
struct tm * ti = localtime(&rawtime);
int v[10000];
RBTree<int> t;
multiset<int> s;
int time1 = ti->tm_min * 60 + ti->tm_sec;
cout << "RBtree開始插入數據,當前時間:" << time1 << "秒" << endl;
for (int i = 0; i < num; i++) {
int a = rand() % INT_MAX;
t.RBTree_insert(a);
//s.insert(a);
}
time(&rawtime);
ti = localtime(&rawtime);
cout << "插入完成,當前時間:" << ti->tm_min * 60 + ti->tm_sec << ",RBtree用時:"
<< ti->tm_min * 60 + ti->tm_sec - time1<< "秒" << endl;
time1 = ti->tm_min * 60 + ti->tm_sec;
time(&rawtime);
ti = localtime(&rawtime);
cout << "set開始插入數據,當前時間:" << time1 << "秒" << endl;
for (int i = 0; i < num; i++) {
int a = rand() % INT_MAX;
s.insert(a);
}
time(&rawtime);
ti = localtime(&rawtime);
cout << "插入完成,當前時間:" << ti->tm_min * 60 + ti->tm_sec << ",set用時:"
<< ti->tm_min * 60 + ti->tm_sec - time1<<"秒"<<endl;
//t.mid_traverse();
cout << endl;
int cnt = 0;
cout << "xigou" << endl;
}
int main() {
test(pow(10, 7));
return 0;
//system("pause");
}
我分別用自己的設計的RBtree與STL的multiset分別插入100萬數據,下面是運行時間:
RBtree用時28秒,set用時166秒,是RBtree的5到6倍,這個差距已經不小了。
下面是我的代碼:
#pragma once
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
enum color
{
red,
black
};
template<typename T>
struct RB_TreeNode
{
RB_TreeNode * left;
RB_TreeNode * right;
RB_TreeNode * p;
static RB_TreeNode<T> * _Guard;
T val;
color color;
RB_TreeNode (T x) :val(x), left(_Guard), right(_Guard), p(_Guard), color(red) {};
RB_TreeNode () : left(NULL), right(NULL), p(NULL), color(black) {};
void operator=(RB_TreeNode<T>& oth) {
left = oth.left;
color = oth.color;
right = oth.right;
val = oth.val;
p = oth.p;
}
};
template<typename T>
RB_TreeNode<T>* RB_TreeNode<T>::_Guard = new RB_TreeNode<T>();
template<typename T>
class RBTree
{
public:
RBTree()
{
_root = _guard;
_len = 0;
}
RBTree(vector<T> v)
{
_root = _guard;
_len = 0;
for (int i = 0; i < v.size(); i++)
{
RBTree_insert(v[i]);
}
}
RBTree(const RBTree<T>& oth) {
_root = copyTree(oth, _guard);
}
//移動構造函數
RBTree(RBTree<T>&& oth) {
_root = oth._root;
}
RB_TreeNode<int>* guard() {
return _guard;
}
bool operator=(RBTree<T>& oth) {
clear();//在拷貝之前,先要釋放已有資源
_root = copyTree(oth, _guard);
}
//當參數爲右值引用
bool operator=(RBTree<T>&& oth) {
clear();//在指向傳進來的節點之前,要先釋放原來的資源;
_root = oth.root;
}
~RBTree()
{
clear();
}
void clear() {
if (_root == NULL)
{
_len = 0;
return;
}
cout << "開始釋放已有資源" << endl;
distroy(_root);
_root = NULL;
_len = 0;
}
int size()
{
return _len;
}
RB_TreeNode<T> * getroot()
{
return _root;
}
////插入節點
void RBTree_insert(int value)
{
RB_TreeNode<T> * Tnode = new RB_TreeNode<T> (value);
RB_TreeNode<T> * tmp = _root;
RB_TreeNode<T> * Ptmp =_guard;
if (_root == _guard)
{
_root = Tnode;
_root->color = black;
_len++;
return;
}
while (tmp!= _guard)
{
Ptmp = tmp;
if (tmp->val > value)
tmp = tmp->left;
else
tmp = tmp->right;
}
Tnode->p = Ptmp;
if (Tnode->val < Ptmp->val)
Ptmp->left = Tnode;
else
Ptmp->right = Tnode;
if(Tnode->p->color==red)
RBINSERT_Fixup(Tnode);
_len++;
}
///調整紅黑樹滿足紅黑樹五個特性
void RBINSERT_Fixup(RB_TreeNode<T> * t)
{
RB_TreeNode<T> * tmp = t->p;
RB_TreeNode<T> * Pbra = _guard;
while (tmp->color==red)
{
if (tmp == tmp->p->left)
{
Pbra = tmp->p->right;
if (Pbra!=_guard&&Pbra->color == red)
{
tmp->color = black;
tmp->p->color = red;
Pbra->color = black;
t = tmp->p;
tmp = t->p;
}
else
{
if (t == tmp->right)
{
Left_Rotate(tmp);
tmp = t;
}
tmp->color = black;
tmp->p->color = red;
Right_Rotate(tmp->p);
}
}
else
{
Pbra = tmp->p->left;
if (Pbra!=_guard&&Pbra->color == red)
{
tmp->color = black;
tmp->p->color = red;
Pbra->color = black;
t = tmp->p;
tmp = t->p;
}
else
{
if (t == tmp->left)
{
Right_Rotate(tmp);
tmp = t;
}
tmp->color = black;
tmp->p->color = red;
Left_Rotate(tmp->p);
}
}
if (tmp==_guard)
{
tmp = t;
tmp->color = black;
}
}
}
/////刪除節點
void RBTree_delete(int value)
{
RB_TreeNode<T> * t = RBTree_serch(value);
if (!t) return;
RB_TreeNode<T> * tmp;
if (t->left&&t->right)
{
t->val = findSucceed(t)->val;
t = findSucceed(t);
}
if (!t->left)
tmp = t->right;
else
tmp = t->left;
if (!t->p) _root = tmp;
else if (t == t->p->left)
t->p->left = tmp;
else
t->p->right = tmp;
tmp->p = t->p;
if (t->color==black)
{
RBDELETE_Fixup(tmp);
}
_len--;
delete t;
t = NULL;
return;
}
///調整紅黑樹滿足紅黑樹五個特性
void RBDELETE_Fixup(RB_TreeNode<T> * t)
{
RB_TreeNode<T> * w = NULL;
while (t!=_root&&t->color==black)
{
if (t == t->p->left)
{
w = t->p->right;
if (w->color == red)
{
t->p->color = red;
w->color = black;
Left_Rotate(t->p);
}
else
{
if (w->right!=_guard&&w->right->color == red)
{
w->color = t->p->color;
t->p->color = black;
w->right->color = black;
Left_Rotate(t->p);
t = _root;
}
else if (w->left != _guard&&w->left->color == red)
{
w->color = red;
w->left->color = black;
Right_Rotate(w);
w = w->p;
}
else
{
w->color = red;
t = t->p;
}
}
}
else
{
w = t->p->right;
if (w->color == red)
{
t->p->color = red;
w->color = black;
Right_Rotate(t->p);
}
else
{
w = t->p->left;
if (w->left != _guard&&w->left->color == red)
{
w->color = t->p->color;
t->p->color = black;
w->left->color = black;
Right_Rotate(t->p);
t = _root;
}
else if (w->right != _guard&&w->right->color == red)
{
Left_Rotate(w);
w = w->p;
}
else
{
w->color = red;
t = t->p;
}
}
}
}
t->color = black;
}
/////尋找節點
RB_TreeNode<T> * RBTree_serch(int value)
{
RB_TreeNode<T> * p = _root;
while (p != _guard)
{
if (p->val == value) return p;
if (p->val < value)
p = p->right;
else
p = p->left;
}
return p;
}
///////尋找前驅
RB_TreeNode<T> * findFront(RB_TreeNode<T> * t)
{
if (t == _guard) return t;
if (t->left != _guard)
{
RB_TreeNode<T> * tmp = t->left;
while (tmp->right != _guard)
tmp = tmp->right;
return tmp;
}
else
{
RB_TreeNode<T> * tmp = t->p;
if (tmp == _guard ||t == tmp->right)
return tmp;
while (tmp->p != _guard&&tmp == tmp->p->left)
tmp = tmp->p;
return tmp->p;
}
}
/////尋找後繼
RB_TreeNode<T> * findSucceed(RB_TreeNode<T> * t)
{
if (t == _guard) return t;
if (t->right != _guard)
{
RB_TreeNode<T> * tmp = t->right;
while (tmp->left != _guard)
tmp = tmp->left;
return tmp;
}
else
{
RB_TreeNode<T> * tmp = t->p;
if (tmp != _guard || t == tmp->left)
return tmp;
while (tmp->p != _guard&&tmp == tmp->p->right)
tmp = tmp->p;
return tmp->p;
}
}
//////左旋
void Left_Rotate(RB_TreeNode<T> * t)
{
if (t == _guard || t->right == _guard)
{
cout << "左旋節點或節點右孩子不應爲空" << endl;
return;
}
RB_TreeNode<T> * tmp = t->right;
tmp->p = t->p;
if (t->p==_guard)
{
_root = tmp;
}
else if (t == t->p->left)
t->p->left = tmp;
else
t->p->right = tmp;
t->p = tmp;
t->right = tmp->left;
if(tmp->left != _guard)
tmp->left->p = t;
tmp->left = t;
}
////右旋
void Right_Rotate(RB_TreeNode<T> * t)
{
if (!t || !t->left)
{
cout << "右旋節點或節點左孩子不應爲空" << endl;
return;
}
RB_TreeNode<T> * tmp = t->left;
tmp->p = t->p;
if(t->p==_guard)
{
_root = tmp;
}
else if (t == t->p->left)
t->p->left = tmp;
else
t->p->right = tmp;
t->p = tmp;
t->left = tmp->right;
if(tmp->right != _guard)
tmp->right->p = t;
tmp->right = t;
}
/////前序遍歷
void pre_traverse()
{
}
////中序遍歷
void mid_traverse(int* pt=NULL)
{
RB_TreeNode<T> * p = _root;
stack<RB_TreeNode<T> *> s;
while (true)
{
while (p!=_guard)
{
s.push(p);
p = p->left;
}
if (s.empty()) break;
p = s.top();
if (pt == NULL)
cout << p->val << " ";
else
*(pt++) = p->val;
s.pop();
p = p->right;
}
}
/////後序遍歷
void post_traverse() {
}
/////層次遍歷
void Print() {
RB_TreeNode<T> * pRoot = _root;
if (!pRoot) return ;
vector<queue<RB_TreeNode<T> *> > vq(2);
int index = 0;
vq[index].push(pRoot);
while (!vq[index].empty() || !vq[1 - index].empty())
{
while (!vq[index].empty())
{
RB_TreeNode<T> * p = vq[index].front();
vq[index].pop();
cout << p << " ";
if (p->left != _guard)
vq[1 - index].push(p->left);
if (p->right != _guard)
vq[1 - index].push(p->right);
}
cout << endl;
index = 1 - index;
}
}
private:
RB_TreeNode<T> * copyTree(const RB_TreeNode<T>* oth, RB_TreeNode<T>* p) {
if (oth == _guard) return _guard;
RB_TreeNode<T>* root = new RB_TreeNode(oth->val);
root->color = oth->color;
root->p = p;
root->left = copyTree(oth->left,root);
root->right = copyTree(oth->right,root);
return root;
}
void distroy(RB_TreeNode<T>* root) {
if (root == _guard) return;
distroy(root->left);
distroy(root->right);
delete root;
}
static RB_TreeNode<T> * _guard;
RB_TreeNode<T> * _root;
int _len;
//friend ostream& operator<<(ostream &out, RB_TreeNode<T> * outT);
};
template<typename T>
RB_TreeNode<T>* RBTree<T>::_guard = RB_TreeNode<T> ::_Guard;
template<typename T>
ostream& operator << (ostream &out, RB_TreeNode<T> * outT)
{
if (!outT) return out;
cout << "[" << " " << "val:" << outT->val << " ";
if(outT->color==0)
cout<< "color:" << "red"<< " ";
else
cout << "color:" << "black" << " ";
if (outT->left != RB_TreeNode<T> ::_Guard)
cout << "left:" << outT->left->val << " ";
if (outT->right != RB_TreeNode<T> ::_Guard)
cout << "right:" << outT->right->val << " ";
if(outT->p != RB_TreeNode<T> ::_Guard)
cout << "parent:" << outT->p->val << " ";
cout << "]";
return out;
}