参考了CLRS(算法导论第二版十二十三章的内容),为了能让红黑树继承搜索二叉树中的大部分方法,我修改了书中红黑树的实现方式,即不再将空节点视为黑色节点,这样一来,红黑树的规则变成了四条。
- 根节点为黑色
- 从任一节点,到叶子节点(这里的叶子节点不是空节点)的所有路径中,包含了相同个数的黑节点
- 任一节点非红即黑
- 任一节点,若其为红,则其孩子要么都为空,要么都为黑节点。
下面是搜索二叉树的实现
//e:\Projects\CLRS\CLRS\BinaryTree.h
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <fstream>
#include <cassert>
using namespace std;
template<class T,class P>
class TreeNode
{
public:
TreeNode(T _key,P * pdata = NULL)
{
key = _key;
sateliteData = pdata;
parentNode = rightNode = leftNode = NULL;
}
T key;
P * sateliteData;
TreeNode * leftNode;
TreeNode * rightNode;
TreeNode * parentNode;
};
template<class T,class P>
class BinaryTree
{
public:
BinaryTree()
{
root = NULL;
}
TreeNode<T,P> * root;
void Inorder_Walk(ofstream &fout);
void Inorder_Walk(TreeNode<T,P>* node,ofstream & fout);
void Preorder_Walk(ofstream &fout);//前序
void Preorder_Walk(TreeNode<T,P>* node,ofstream & fout,int level);
TreeNode<T,P> * Search(T key);
TreeNode<T,P> * Search(TreeNode<T,P>* node,T key);
TreeNode<T,P> * Iterative_Search(T key);
TreeNode<T,P> * Iterative_Search(TreeNode<T,P>* node,T key);
TreeNode<T,P>* Min(TreeNode<T,P>* node);
TreeNode<T,P>* Min();
TreeNode<T,P>* Max(TreeNode<T,P>* node);
TreeNode<T,P>* Max();
TreeNode<T,P>* TreeSuccessor(TreeNode<T,P>* node);
TreeNode<T,P>* Insert(TreeNode<T,P>* z);
TreeNode<T,P>* Delete(TreeNode<T,P>* z,TreeNode<T,P>*& x,TreeNode<T,P>*& p);
void LeftRotate(TreeNode<T,P>* x);
void RightRotate(TreeNode<T,P>* y);
bool IsSorted(); //是二叉搜索树吗
bool IsSorted(TreeNode<T,P>* node,T& minVal,T& maxVal); //是二叉搜索树吗
};
template<class T,class P>
bool BinaryTree<T,P>::IsSorted()
{
if (root == NULL)
{
return true;
}
T minV,maxV;
return IsSorted(root,minV,maxV);
}
template<class T,class P>
bool BinaryTree<T,P>::IsSorted(TreeNode<T,P>* node,T& minV,T&maxV)
{
T lminV,lmaxV;
T rminV,rmaxV;
if (node->leftNode!=NULL)
{
bool res = IsSorted(node->leftNode,lminV,lmaxV);
if (!res)
{
return false;
}
}
if (node->rightNode!=NULL)
{
bool res = IsSorted(node->rightNode,rminV,rmaxV);
if (!res)
{
return false;
}
}
if (node->leftNode!=NULL)
{
if (lmaxV>node->key)
{
return false;
}
}
if (node->rightNode!=NULL)
{
if (rminV < node->key)
{
return false;
}
}
if (node->leftNode == NULL)
{
minV = node->key;
}else{
minV = lminV;
}
if (node->rightNode == NULL)
{
maxV = node->key;
}else{
maxV = rmaxV;
}
return true;
}
template<class T,class P>
void BinaryTree<T,P>::Preorder_Walk(ofstream &fout)
{
if (root == NULL)
{
fout << "empty tree"<<endl;
}
Preorder_Walk(root,fout,0);
fout << (IsSorted()?"sorted":"unsorted") << endl;
}
template<class T,class P>
void BinaryTree<T,P>::Preorder_Walk(TreeNode<T,P>* node,ofstream & fout,int level)
{
if (node == NULL)
{
return;
}
for (int i = 0;i<level;i++)
{
fout << "\t";
}
if (node->parentNode!=NULL && node->parentNode->leftNode == node)
{
fout << "L:";
}
if (node->parentNode!=NULL && node->parentNode->rightNode == node)
{
fout << "R:";
}
fout << node->key << endl;
Preorder_Walk(node->leftNode,fout,level + 1);
Preorder_Walk(node->rightNode,fout,level + 1);
}
template<class T,class P>
void BinaryTree<T,P>::LeftRotate(TreeNode<T,P>* x)
{
assert(x != NULL);
assert(x->rightNode !=NULL);
TreeNode<T,P>* y = x->rightNode;
TreeNode<T,P>* p = x->parentNode;
x->rightNode = y->leftNode;
if (x->rightNode)
{
x->rightNode->parentNode = x;
}
y->parentNode = p;
if (p)
{
if (x == p->leftNode)
p->leftNode = y;
else
p->rightNode = y;
}else{
root = y;
}
x->parentNode = y;
y->leftNode = x;
}
template<class T,class P>
void BinaryTree<T,P>::RightRotate(TreeNode<T,P>* y)
{
assert(y != NULL);
assert(y->leftNode !=NULL);
TreeNode<T,P>* x = y->leftNode;
TreeNode<T,P>* p = y->parentNode;
y->leftNode = x->rightNode;
if (y->leftNode)
{
y->leftNode->parentNode = y;
}
x->parentNode = p;
if (p)
{
if (y == p->leftNode)
p->leftNode = x;
else
p->rightNode = x;
}else{
root = x;
}
y->parentNode = x;
x->rightNode = y;
}
//返回x为被删节点的孩子,p为被删节点的父亲(两者都可能为空)
template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Delete(TreeNode<T,P>* z,TreeNode<T,P>*& x,TreeNode<T,P>*& p)
{
if (z == NULL)
{
x = p = NULL;
return NULL;
}
TreeNode<T,P>* y;
if (z->leftNode == NULL || z->rightNode == NULL)
{
y = z;
}else
{
y = TreeSuccessor(z);
}
//////////////////////////////////////////////////////////////////////////
//y 最多只有一个孩子
if (y->leftNode!=NULL)
{
x = y->leftNode;
}else{
x = y->rightNode;
}
//如果x为空,则y没有孩子
p = y->parentNode;
if (x != NULL)
{
x->parentNode = p;
}
if (p == NULL)
{
root = x;
}else{
if (y == p->leftNode)
p->leftNode = x;
else
p->rightNode = x;
}
if (y!=z)
{
z->key = y->key;
z->sateliteData = y->sateliteData;
}
return y;
}
//返回插入节点的父节点
template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Insert(TreeNode<T,P>* z)
{
TreeNode<T,P>* y = NULL;
TreeNode<T,P>* x = root;
while (x != NULL)
{
y = x;
if (z->key < x->key)
{
x = x->leftNode;
}else{
x = x->rightNode;
}
}
z->parentNode = y;
if (y == NULL)
{
root = z;
}else{
if (z->key < y->key)
{
y->leftNode = z;
}else
{
y->rightNode = z;
}
}
return y;
}
template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::TreeSuccessor(TreeNode<T,P>* node)
{
if (node == NULL)
{
return NULL;
}
if (node->rightNode!=NULL)
{
return Min(node->rightNode);
}
TreeNode<T,P>* y = node->parentNode;
while (y!=NULL && y->rightNode==node) //node是y的右孩子
{
node = y;
y = node->parentNode;
}
return y;
}
template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Max()
{
return Max(root);
}
template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Max(TreeNode<T,P>* node)
{
if (node == NULL)
{
return NULL;
}
if (node->rightNode!=NULL)
{
node = node->rightNode;
}
return node;
}
template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Min()
{
return Min(root);
}
template<class T,class P>
TreeNode<T,P>* BinaryTree<T,P>::Min(TreeNode<T,P>* node)
{
if (node == NULL)
{
return NULL;
}
if (node->leftNode!=NULL)
{
node = node->leftNode;
}
return node;
}
template<class T,class P>
void BinaryTree<T,P>::Inorder_Walk(ofstream & fout)
{
Inorder_Walk(root,fout);
}
template<class T,class P>
void BinaryTree<T,P>::Inorder_Walk(TreeNode<T,P>* node,ofstream & fout)
{
if (node != NULL)
{
Inorder_Walk(node->leftNode,fout);
fout << node->key << endl;
Inorder_Walk(node->rightNode,fout);
}
}
template<class T,class P>
TreeNode<T,P> * BinaryTree<T,P>::Search(T key)
{
return Search(root,key);
}
template<class T,class P>
TreeNode<T,P> * BinaryTree<T,P>::Search(TreeNode<T,P>* node,T key)
{
if (node == NULL || node->key == key)
{
return node;
}
if (key < node->key)
{
return Search(node->leftNode,key);
}
return Search(node->rightNode,key);
}
template<class T,class P>
TreeNode<T,P> * BinaryTree<T,P>::Iterative_Search(T key)
{
return Iterative_Search(root,key);
}
template<class T,class P>
TreeNode<T,P> * BinaryTree<T,P>::Iterative_Search(TreeNode<T,P>* node,T key)
{
while (node != NULL && node->key!=key)
{
if (key < node->key)
{
node = node->leftNode;
}else
{
node = node->rightNode;
}
}
return node;
}
#endif
红黑树继承了上面的搜索二叉树,代码如下
//e:\Projects\CLRS\CLRS\RBTree.h
#ifndef RBTREE_H
#define RBTREE_H
#include <queue>
using namespace std;
/*
我们的实现不采用书中的NIL叶的概念,这样需要4个ruler
1. 每个节点非红即黑(null没有颜色的概念)
2. 根是黑色的(如果树为空,颜色就没了)
3. 若某个节点node为红,则其孩子都是黑的
4. 对每个节点,其到子孙叶子节点的路径上,所包含的黑色数相同
由4和3,隐含的一点就是,某个节点为红,则其要么两个孩子为空,要么都是黑孩子。
*/
enum NodeColor
{
BLACK,
RED
};
template<class T,class P>
class RBNode:public TreeNode<T,P>
{
public:
RBNode(T key,P* pData = NULL):TreeNode<T,P>(key,pData)
{
}
NodeColor color;
};
template<class T,class P>
class RBTree:public BinaryTree<T,P>
{
public:
RBTree():BinaryTree<T,P>()
{
}
void Insert(RBNode<T,P>* z);
RBNode<T,P>* Delete(RBNode<T,P>* z);
void Preorder_Walk(ofstream &fout);
void Preorder_Walk(RBNode<T,P>* node,ofstream & fout,int level);
bool IsRBTree(); //计算是否符合红黑树的条件
int GetBlackNodes(RBNode<T,P>* node);//获取node到底的黑节点个数,如果不符合红黑树的条件,则返回-1
//RBNode<T,P> * Search(T key);
};
template<class T,class P>
int RBTree<T,P>::GetBlackNodes(RBNode<T,P>* node)
{
RBNode<T,P> * nl = (RBNode<T,P>*)node->leftNode;
RBNode<T,P> * nr = (RBNode<T,P>*)node->rightNode;
int lnum = 0;
int rnum = 0;
if(nl!=NULL)
{
lnum = GetBlackNodes(nl);
if (lnum == -1)
{
return -1;
}
}
if (nr !=NULL)
{
rnum = GetBlackNodes(nr);
if (rnum == -1)
{
return -1;
}
}
if(lnum != rnum)
return -1;
return lnum + (node->color == BLACK);
}
template<class T,class P>
bool RBTree<T,P>::IsRBTree()
{
if (root == NULL)
{
return true;
}
if(((RBNode<T,P>*)root)->color == RED)
return false;
queue<RBNode<T,P>* > nodes;
nodes.push((RBNode<T,P>*)root);
while (!nodes.empty())
{
RBNode<T,P>* node = nodes.front();
nodes.pop();
RBNode<T,P> * nl = (RBNode<T,P>*)node->leftNode;
RBNode<T,P> * nr = (RBNode<T,P>*)node->rightNode;
if (node->color == RED)
{
if ((nl==NULL && nr == NULL) ||
(nl!=NULL && nr != NULL && nl->color == BLACK && nr->color == BLACK))
{
//do nothing
}else{
return false;
}
}
if (nl!=NULL)
{
nodes.push(nl);
}
if (nr!=NULL)
{
nodes.push(nr);
}
}
int blackNodeNum = GetBlackNodes((RBNode<T,P>*)root);
if (blackNodeNum == -1)
{
return false;
}
return true;
}
//template<class T,class P>
//RBNode<T,P>* RBTree<T,P>::Search(T key)
//{
// TreeNode<T,P>* node = BinaryTree<T,P>::Search(key);
// return (RBNode<T,P>*)node;
//}
//
template<class T,class P>
void RBTree<T,P>::Preorder_Walk(ofstream &fout)
{
if (root == NULL)
{
fout << "empty tree"<<endl;
}
Preorder_Walk((RBNode<T,P>*)root,fout,0);
fout << (IsSorted()?"sorted":"unsorted") << endl;
fout << (IsRBTree()?"rbtree":"not a rbtree") << endl;
}
//以后可以传入一个函数指针visit节点
template<class T,class P>
void RBTree<T,P>::Preorder_Walk(RBNode<T,P>* node,ofstream & fout,int level)
{
if (node == NULL)
{
return;
}
for (int i = 0;i<level;i++)
{
fout << "\t";
}
if (node->parentNode!=NULL && node->parentNode->leftNode == node)
{
fout << "L:";
}
if (node->parentNode!=NULL && node->parentNode->rightNode == node)
{
fout << "R:";
}
fout << node->key << " " << (node->color == RED? "red":"black") << endl;
Preorder_Walk((RBNode<T,P>*)node->leftNode,fout,level + 1);
Preorder_Walk((RBNode<T,P>*)node->rightNode,fout,level + 1);
}
//
template<class T,class P>
RBNode<T,P>* RBTree<T,P>::Delete(RBNode<T,P>* z)
{
RBNode<T,P>* x;
RBNode<T,P>* p;
TreeNode<T,P>* _x;
TreeNode<T,P>* _p;
RBNode<T,P>* y = (RBNode<T,P>*)BinaryTree<T,P>::Delete(z,_x,_p);
x = (RBNode<T,P>*)_x;
p = (RBNode<T,P>*)_p;
//x为被删节点y的孩子,p为y的父亲,现在为x的父亲
if (y==NULL || y->color == RED)
{
return y;
}
//y为黑色节点
while (x != root && (x == NULL || x->color == BLACK))
{
RBNode<T,P>* w;
if (x == p->leftNode)//p不可能为null,否则x就为root了,就不会进入此循环
{
w = (RBNode<T,P>*)p->rightNode;//w必定不空
//case 1
if (w->color == RED) //此时w的两个孩子均为黑节点(非空)
{
p->color = RED;
w->color = BLACK;
LeftRotate(p);
w = (RBNode<T,P>*)p->rightNode;
}
//w必定是黑节点(非空),p的颜色未知
RBNode<T,P>* wl = (RBNode<T,P>*)w->leftNode;
RBNode<T,P>* wr = (RBNode<T,P>*)w->rightNode;
if ((wl == NULL && wr == NULL) ||
( wl!=NULL&&wr!=NULL &&
wl->color == BLACK && wr->color == BLACK)
)
{
//case 2
w->color = RED;
x = p;
}else{
//case 3
if(wr == NULL || wr->color == BLACK)
{
//w->leftNode必为红
wl->color = BLACK;
RightRotate(w);
w = (RBNode<T,P>*)p->rightNode;
}
//case 4
//此时 w->right必为红
wr = (RBNode<T,P>*)w->rightNode;
wr->color = BLACK;
w->color = p->color;
p->color = BLACK;
LeftRotate(p);
x = (RBNode<T,P>*)root;
}
}else{
w = (RBNode<T,P>*)p->leftNode;//w必定不空
//case 1
if (w->color == RED) //此时w的两个孩子均为黑节点(非空)
{
p->color = RED;
w->color = BLACK;
RightRotate(p);
w = (RBNode<T,P>*)p->leftNode;
}
//w必定是黑节点(非空),p的颜色未知
RBNode<T,P>* wl = (RBNode<T,P>*)w->leftNode;
RBNode<T,P>* wr = (RBNode<T,P>*)w->rightNode;
if ((wl == NULL && wr == NULL) ||
( wl!=NULL&&wr!=NULL &&
wl->color == BLACK && wr->color == BLACK)
)
{
//case 2
w->color = RED;
x = p;
}else{
//case 3
if(wl == NULL || wl->color == BLACK)
{
//w->rightNode必为红
wr->color = BLACK;
LeftRotate(w);
w = (RBNode<T,P>*)p->leftNode;
}
//case 4
//此时 w->left必为红
wl = (RBNode<T,P>*)w->leftNode;
wl->color = BLACK;
w->color = p->color;
p->color = BLACK;
RightRotate(p);
x = (RBNode<T,P>*)root;
}
}
if (x!=NULL)
{
p = (RBNode<T,P>*)x->parentNode;
}
}
if(x!=NULL)
x->color = BLACK;
return y;
}
template<class T,class P>
void RBTree<T,P>::Insert(RBNode<T,P>* z)
{
//z是外面生成的节点;
RBNode<T,P>* parent = (RBNode<T,P>*)BinaryTree<T,P>::Insert((TreeNode<T,P>*)z);//返回为新插入点的父亲
z->color = RED;
z->leftNode = z->rightNode = NULL;
RBNode<T,P> * uncle;
RBNode<T,P>* grandParent;
//RBInsertFixup
while (parent!=NULL && parent->color == RED)
{
RBNode<T,P>* grandParent = (RBNode<T,P>*)parent->parentNode;//grandParent肯定非空,且为黑色
if (parent == grandParent->leftNode)//parent是左孩子
{
uncle = (RBNode<T,P>*)grandParent->rightNode;
//如果uncle是红色,则
if (uncle!=NULL && uncle->color == RED)
{
parent->color = uncle->color = BLACK;
grandParent->color = RED;
z = grandParent;
}else{//uncle是黑色或空
if (z == parent->rightNode) //z是右孩子
{
z = parent;
LeftRotate(z);
parent = (RBNode<T,P>*)z->parentNode;
}
parent->color = BLACK;
grandParent->color = RED;
RightRotate((TreeNode<T,P>*)grandParent);
//此时结束了
}
}else{ //parent是右孩子
uncle = (RBNode<T,P>*)grandParent->leftNode;
if (uncle!=NULL && uncle->color == RED)
{
parent->color = uncle->color = BLACK;
grandParent->color = RED;
z = grandParent;
}else{
if (z == parent->leftNode)
{
z = parent;
RightRotate(z);
parent = (RBNode<T,P>*)z->parentNode;
}
parent->color = BLACK;
grandParent->color = RED;
LeftRotate(grandParent);
}
}
parent = (RBNode<T,P>*)z->parentNode;
}
((RBNode<T,P>*)root)->color = BLACK;
}
#endif
测试代码如下 #include "BinaryTree.h"
#include "RBTree.h"
#include "algorithm.h"
#include <vector>
#include <iostream>
#include <fstream>
using namespace std;
using namespace CLRS;
void TestInsertSort()
{
int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
InsertSort(arr,sizeof(arr) / sizeof(int));
copy(arr,arr + sizeof(arr) / sizeof(int),ostream_iterator<int>(cout, "\t"));
cout << endl;
}
void TestMergeSort()
{
int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
InsertSort(arr,sizeof(arr) / sizeof(int));
copy(arr,arr + sizeof(arr) / sizeof(int),ostream_iterator<int>(cout, "\t"));
cout << endl;
}
void TestRBTree()
{
ofstream fout("log.txt");
RBTree<int,int> tree;
int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
for (int i = 0;i<sizeof(arr) / sizeof(int);i++)
{
RBNode<int,int> * node = new RBNode<int,int>(arr[i]);
tree.Insert(node);
fout << "after:"<<arr[i]<<" inserted"<<endl;
tree.Preorder_Walk(fout);
}
int arr2[] = {5,4,1,2,3,8,9,32,1,5,7,213,7,6,3,345,52};
for (int i = 0;i<sizeof(arr2) / sizeof(int);i++)
{
RBNode<int,int>* node = (RBNode<int,int>*)tree.Search(arr2[i]);
if (node != NULL)
{
RBNode<int,int>* _node = tree.Delete(node);
delete _node;
fout << arr2[i] <<" deleted"<<endl;
tree.Preorder_Walk(fout);
}
}
fout.close();
}
void TestBinaryTree()
{
ofstream fout("log.txt");
BinaryTree<int,int> tree;
int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
//int arr[] = {4,1,2,1,3,3};
for (int i = 0;i<sizeof(arr) / sizeof(int);i++)
{
tree.Insert(new TreeNode<int,int>(arr[i]));
fout << "after:"<<arr[i]<<" inserted"<<endl;
tree.Preorder_Walk(fout);
}
int arr2[] = {5,4,1,2,3,8,9,32,1,5,7,213,7,6,3,345,52};
for (int i = 0;i<sizeof(arr2) / sizeof(int);i++)
{
TreeNode<int,int>* node = tree.Search(arr2[i]);
if (node != NULL)
{
TreeNode<int,int>* x;
TreeNode<int,int>* p;
TreeNode<int,int>* _node = tree.Delete(node,x,p);
delete _node;
fout << arr2[i] <<" deleted"<<endl;
tree.Preorder_Walk(fout);
}
}
fout.close();
}
//template<class T,class P>
//class A
//{
//public:
// void func2(int x)
// {
// cout << "A<T,P>::func2"<<endl;
// }
//};
//template<class T,class P>
//class B:public A<T,P>
//{
//public:
// int func2()
// {
// A<T,P>::func2(4);
// cout << "B<T,P>:func2"<<endl;
// return 0;
// }
//};
//void Test()
//{
// B<int,int> b;
// A<int,int>* pa = &b;
// B<int,int>* pb = &b;
// cout << (pa == pb) << endl;
// b.func2();
//}
int main(int argc,char* argv[])
{
//TestInsertSort();
//TestMergeSort();
//TestBinaryTree();
TestRBTree();
//Test();
return 0;
}