参考了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; }