Description
实现红黑树,并比较与简单二分搜索树的执行效率
Input
The input will be 3 lines:
In the first line, there are two integers m and n, denoting the number of node number and the number of nodes to be searched
In the second line, there are m integers denoting the inserting number to the RB tree
In the third line, there are n numbers denoting the numbers to be searched
Output
Your program should first output the RB tree using preorder procedure, associating each node with the color. Then you should output the compare number of each of the search.
Sample Input
9 37 2 11 1 5 4 8 14 157 2 15
Sample Output
7:black2:red1:black5:black4:red11:red8:black14:black15:red013
HINT
#include <iostream>
using namespace std;
struct Key { int value; };
struct RBTNode {
Key key;
int lcount;
int rcount;
RBTNode *lchild;
RBTNode *rchild;
RBTNode *parent;
bool color;
};
class RBT {
private:
const static bool RED = true;
const static bool BLACK = false;
void clear() {
RBTNode* p = m_root;
while (p != m_null) {
if (p->lchild != m_null) {
p = p->lchild;
}
else if (p->rchild != m_null) {
p = p->rchild;
}
else {
RBTNode* temp = p;
p = p->parent;
if (temp == p->lchild) {
p->lchild = m_null;
}
else {
p->rchild = m_null;
}
delete temp;
}
}
m_root = m_null;
}
int keyCmp(const Key& key1, const Key& key2);
void insertFixup(RBTNode* insertNode);
void leftRotate(RBTNode* node);
void rightRotate(RBTNode* node);
public:
RBT() {
m_null = new RBTNode;
m_null->color = BLACK;
m_null->lchild = m_null->rchild = m_null;
m_root = m_null;
}
~RBT() {
clear();
delete m_null;
}
RBTNode* m_null;
RBTNode* m_root;
void print(RBTNode *&m_root);
//void print(int m);
void insert(const Key& key);
int search(const Key& key);
};
void RBT::insertFixup(RBTNode* insertNode)
{
RBTNode *p = insertNode;
while (p->parent->color == RED) {
if (p->parent == p->parent->parent->lchild) {
RBTNode* parentRight = p->parent->parent->rchild;
if (parentRight->color == RED) {
p->parent->color = BLACK;
parentRight->color = BLACK;
p->parent->parent->color = RED;
p = p->parent->parent;
}
else {
if (p == p->parent->rchild) {
p = p->parent;
leftRotate(p);
}
p->parent->color = BLACK;
p->parent->parent->color = RED;
rightRotate(p->parent->parent);
}
}
else {
RBTNode* parentLeft = p->parent->parent->lchild;
if (parentLeft->color == RED) {
p->parent->color = BLACK;
parentLeft->color = BLACK;
p->parent->parent->color = RED;
p = p->parent->parent;
}
else {
if (p == p->parent->lchild) {
p = p->parent;
//rightRotate(p->parent->parent);
rightRotate(p);
}
p->parent->color = BLACK;
p->parent->parent->color = RED;
leftRotate(p->parent->parent);
}
}
}
m_root->color = BLACK;
}
void RBT::leftRotate(RBTNode* node) {
//把一个节点向左下方移一格,并让它原来的右子节点代替它的位置。
RBTNode* right = node->rchild;
node->rchild = right->lchild;
node->rcount = right->lcount;
node->rchild->parent = node;
right->parent = node->parent;
if (right->parent == m_null) {
m_root = right;
}
else if (node == node->parent->lchild) {
node->parent->lchild = right;
}
else {
node->parent->rchild = right;
}
right -> lchild = node;
right->lcount += node->lcount + 1;
node->parent = right;
}
void RBT::rightRotate(RBTNode* node) {
//把一个节点向右下方移一格,并让它原来的左子节点代替它的位置。
RBTNode* left = node ->lchild;
node -> lchild = left -> rchild;
node -> lcount = left -> rcount;
node -> lchild -> parent = node;
left -> parent = node -> parent;
if (left->parent == m_null) {
m_root = left;
}
else if (node == node->parent->lchild) {
node->parent->lchild = left;
}
else {
node->parent->rchild = left;
}
left->rchild = node;
left->rcount += node->rcount + 1;
node->parent = left;
}
void RBT::insert(const Key& key) {//插入一个节点
RBTNode* node = new RBTNode;
node->key = key;
node->lcount = 0;
node->rcount = 0;
node->lchild = m_null;
node->rchild = m_null;
node->color = RED;
RBTNode* p = m_root;
RBTNode* leaf = m_null;
while (p != m_null) {
leaf = p;
if (keyCmp(node->key, p->key) < 0) {
p->lcount++;
p = p->lchild;
}
else {
p->rcount++;
p = p->rchild;
}
}
node->parent = leaf;
if (leaf == m_null) {//如果是空树。
m_root = node;
node->parent = m_root;
}
else if (keyCmp(node->key, leaf->key) < 0) {
leaf->lchild = node;
}
else {
leaf->rchild = node;
}
node->lchild = m_null;
node->rchild = m_null;
node->color = RED;
//修改树,以保持平衡。
insertFixup(node);
}
int RBT::keyCmp(const Key& key1, const Key& key2)
{
return key1.value - key2.value;
}
int RBT::search(const Key& key) {
RBTNode* result = m_root;
int counttt = 0;
while (result != m_null && keyCmp(key, result->key) != 0) {
result = keyCmp(key, result->key) < 0 ? result->lchild : result->rchild;
counttt++;
}
return counttt;
}
void RBT::print(RBTNode *&m_root)
{
if (m_root == m_null)
return;
RBTNode *present = m_root;
cout << present->key.value << ":";
if (present->color == BLACK)
cout << "black" << endl;
else
cout << "red" << endl;
print(present->lchild);
print(present->rchild);
}
int main()
{
int m, n;
//int a[1000];
while (cin >> m >> n)
{
RBT rbt;
Key keynum;
Key searchnum;
for (int i = 0; i < m; i++)
{
cin >> keynum.value;
rbt.insert(keynum);
//rbt.print(rbt.m_root);
//cout << "_______________\n";
}
rbt.print(rbt.m_root);
for (int j = 0; j < n; j++)
{
cin >> searchnum.value;
int compare = rbt.search(searchnum);
cout << compare << endl;
}
}
return 0;
}
/**************************************************************
Problem: ****
User: Avivadepp
Language: C++
Result: Accepted
Time:4 ms
Memory:1284 kb
****************************************************************/