红黑树性质及实现详细介绍:
http://zh.wikipedia.org/zh/%E7%BA%A2%E9%BB%91%E6%A0%91
代码部分:
头文件
// RBTree.h: interface for the CRBTree class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_RBTREE_H__9C701E48_A116_4AE0_8736_B5F45F530AF5__INCLUDED_) #define AFX_RBTREE_H__9C701E48_A116_4AE0_8736_B5F45F530AF5__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define BLACK 0 #define RED 1 #define NULL 0 typedef int BOOL; typedef struct RBTreeNode { int key; int color; struct RBTreeNode *parent, *left, *right; RBTreeNode(){} RBTreeNode(int k):key(k){ // 创建新结点默认颜色为红色 color = RED; parent = NULL; left = NULL; right = NULL;} }RBTree, RBTreeNode; class CRBTree { public: CRBTree(); virtual ~CRBTree(); void RB_InitLeafNode(); BOOL RB_Insert(int keyVal); BOOL RB_Delete(int keyVal); RBTreeNode *RB_Find(int keyVal); void RB_Print(); int RB_GetSize()const { return m_Size; } private: void RB_Insert_FixedUp(RBTreeNode *&pNode); void RB_Del_FixedUp(RBTreeNode *&pNode); void RB_Left_Rotate(RBTreeNode *&pNode); void RB_Right_Rotate(RBTreeNode *&pNode); void RB_Print(RBTreeNode *&pNode); void RB_SwapTwoNodes(RBTreeNode *&pNode1, RBTreeNode *&pNode2); void RB_EmptyTree(RBTreeNode *&pNode); private: RBTree *m_root; //根结点 RBTreeNode *m_NIL; // 空结点 int m_Size; }; #endif // !defined(AFX_RBTREE_H__9C701E48_A116_4AE0_8736_B5F45F530AF5__INCLUDED_)
实现文件
// RBTree.cpp: implementation of the CRBTree class. // ////////////////////////////////////////////////////////////////////// #include <iostream> #include "RBTree.h" using namespace std; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// // 构造函数 CRBTree::CRBTree() { m_root = m_NIL = NULL; m_Size = 0; } // 析构函数 CRBTree::~CRBTree() { RB_EmptyTree(m_root); delete m_NIL; m_root = m_NIL = NULL; cout << "Empty the tree!\n"; } // 初始化叶子结点 void CRBTree::RB_InitLeafNode() { m_root = new RBTree(-1); m_NIL = new RBTreeNode(-1); m_NIL->color = BLACK; // 叶子结点颜色都为黑色 m_NIL->parent = NULL; m_NIL->left = m_NIL->right = NULL; m_root = m_NIL; m_root->parent = m_NIL; } // 插入树结点 BOOL CRBTree::RB_Insert( int keyVal ) { RBTreeNode *pNewNode = new RBTreeNode(keyVal); pNewNode->left = m_NIL; pNewNode->right = m_NIL; RBTreeNode *pNode = m_root; RBTreeNode *pPreNode = m_NIL; while(pNode != m_NIL) // 树不为空 { pPreNode = pNode; if (keyVal < pNode->key) { pNode = pNode->left; } else if (keyVal > pNode->key) { pNode = pNode->right; } else{ delete pNewNode; return 0; } } pNewNode->parent = pPreNode; if (pPreNode == m_NIL) // 树为空 { pNewNode->color = BLACK; m_root = pNewNode; } else { if (keyVal < pPreNode->key) { pPreNode->left = pNewNode; } else pPreNode->right = pNewNode; } m_Size++; cout << "Insert "<< m_Size << " node: " << keyVal << " succeeded!\n"; RB_Insert_FixedUp(pNewNode); return 1; } // 删除树结点 BOOL CRBTree::RB_Delete( int keyVal ) { RBTreeNode *pDelNode, *pPreNode = m_NIL; if (m_root == m_NIL) { return 0; } // pDelNode = m_root; // while(pDelNode != m_NIL) // { // if (keyVal < pDelNode->key) // { // pPreNode = pDelNode; // pDelNode = pDelNode->left; // } // else if (keyVal > pDelNode->key) // { // pPreNode = pDelNode; // pDelNode = pDelNode->right; // } // else // break; // } pDelNode = RB_Find(keyVal); if (pDelNode == NULL) { return 0; // 没有此结点 } pPreNode = pDelNode->parent; //从该结点的左子树找出最大的结点或从右子树找出最小的结点, 两者的值进行替换 RBTreeNode *pTemp; RBTreeNode *pDelChild; if (pDelNode->left != m_NIL && pDelNode->right != m_NIL) { // 有两个子结点,查找左子树 pTemp = pDelNode->left; while(pTemp->right != m_NIL) { pTemp = pTemp->right; } RB_SwapTwoNodes(pTemp, pDelNode); pDelChild = pTemp->left; pDelChild->parent = pTemp->parent; if (pTemp->parent->left == pTemp) { pTemp->parent->left = pDelChild; } else pTemp->parent->right = pDelChild; } else if (pDelNode->left == m_NIL && pDelNode->right == m_NIL) { // 要删除的结点是叶子结点 if (pPreNode == m_NIL) { delete m_root; m_root = m_NIL; m_Size--; return 1; } else { if (pDelNode == pDelNode->parent->left) { pPreNode->left = m_NIL; } else pPreNode->right = m_NIL; pDelChild = m_NIL; pDelChild->parent = pDelNode->parent; pTemp = pDelNode; } } else // 有一个子结点 { if (pDelNode->left != m_NIL) { pDelChild = pDelNode->left; } else { pDelChild = pDelNode->right; } if (pDelChild == pPreNode->left) { pDelChild->parent = pPreNode; pPreNode->left = pDelChild; } else { pDelChild->parent = pPreNode; pPreNode->right = pDelChild; } pTemp = pDelNode; } if (pTemp->color == BLACK) { RB_Del_FixedUp(pDelChild); } cout << "Deleted node: " << pTemp->key << endl; delete pTemp; m_Size--; return 1; } // 查找指定结点,成功 放回该结点,否则返回NULL RBTreeNode * CRBTree::RB_Find( int keyVal ) { RBTreeNode *pNode; if (m_root == m_NIL) { return NULL; } pNode = m_root; while(pNode != m_NIL) { if (keyVal < pNode->key) { pNode = pNode->left; } else if (keyVal > pNode->key) { pNode = pNode->right; } else{ cout << "Find node: " << keyVal << "succeeded!\n"; return pNode; } } return NULL; } // 插入结点后形成的新结构不满足红黑树性质和对其进行处理 void CRBTree::RB_Insert_FixedUp( RBTreeNode *&pNode ) { while (pNode->parent->color == RED) { RBTreeNode *pNodeParent = pNode->parent; RBTreeNode *pNodePaBro; if (pNodeParent->parent->left == pNodeParent) pNodePaBro = pNodeParent->parent->right; else pNodePaBro = pNodeParent->parent->left; if (pNodePaBro->color == RED) { // 父结点和叔结点都是红色 ==>> 父--黑 叔--黑 祖父--红 pNodeParent->color = BLACK; pNodePaBro->color = BLACK; pNodeParent->parent->color = RED; pNode = pNode->parent->parent; if (pNode == m_NIL) { m_root->color = BLACK; return ; } } /// 红父 黑叔结点 或者没有叔结点 else if(pNodeParent->parent->left == pNodeParent && pNodeParent->left == pNode) { pNodeParent->color = BLACK; pNodeParent->parent->color = RED; RB_Right_Rotate(pNode->parent->parent); break; } else if (pNodeParent->parent->left == pNodeParent && pNodeParent->right == pNode) { pNode = pNode->parent; RB_Left_Rotate(pNode); } else if (pNodeParent->parent->right == pNodeParent && pNodeParent->left == pNode) { pNode = pNode->parent; RB_Right_Rotate(pNode); } else { pNodeParent->color = BLACK; pNodeParent->parent->color = RED; RB_Left_Rotate(pNode->parent->parent); break; } }// while m_root->color = BLACK; } // 删除结点后形成的新结构不满足红黑树性质和对其进行处理 void CRBTree::RB_Del_FixedUp( RBTreeNode *&pNode ) { int nLRFlag; RBTreeNode *pBroNode; while(pNode != m_root && pNode->color == BLACK) { if (pNode->parent->left == pNode) { nLRFlag = 0; pBroNode = pNode->parent->right; } else { nLRFlag = 1; pBroNode = pNode->parent->left; } //1 父-red 无兄 子-red ==>> 子-black //2 父-black 兄-red ==>> 父-red 兄-black 旋转父结点 if (pBroNode->color == RED) { pNode->parent->color = BLACK; pBroNode->color = BLACK; if (nLRFlag == 0) { RB_Left_Rotate(pNode->parent); } else RB_Right_Rotate(pNode->parent); } //3 兄-black 两黑侄 ==>> 兄=红 子=黑 红父=黑 往上遍历(黑父) else if (pBroNode->left->color == BLACK && pBroNode->right->color == BLACK) { pNode->color = BLACK; pBroNode->color = RED; pNode->parent->color = BLACK; pNode = pNode->parent; // 往上遍历 } //4 兄-black 左黑侄右红侄 ==>> 兄=父色 父=黑 侄=黑 (子=黑) 左旋转父节点 else if (pBroNode->left->color == BLACK && pBroNode->right->color == RED) { if (nLRFlag == 0) { pBroNode->color = pNode->parent->color; pNode->parent->color = BLACK; pNode->color = BLACK; pBroNode->right->color = BLACK; RB_Left_Rotate(pNode->parent); break; } else { RBTreeNode *pPa = pNode->parent; pBroNode->left->color = pNode->parent->color; pNode->parent->color = BLACK; RB_Left_Rotate(pBroNode); RB_Right_Rotate(pPa); break; } } //5 兄-black 左红侄右黑侄 ==>> 侄=父色 父=黑 右旋转兄 左旋转父 else if (pBroNode->left->color == RED && pBroNode->right->color == BLACK) { if (nLRFlag == 0) { RBTreeNode *pPa = pNode->parent; pBroNode->left->color = pNode->parent->color; pNode->parent->color = BLACK; RB_Right_Rotate(pBroNode); RB_Left_Rotate(pPa); break; } else { pBroNode->color = pNode->parent->color; pNode->parent->color = BLACK; pNode->color = BLACK; pBroNode->right->color = BLACK; RB_Right_Rotate(pNode->parent); break; } } else //两红侄的情况 转换成一黑一红的情况 { if (nLRFlag == 0) { pBroNode->left->color = BLACK; } else { pBroNode->right->color = BLACK; } } } pNode->color = BLACK; //子 ==> black return; } // 左旋处理 void CRBTree::RB_Left_Rotate( RBTreeNode *&pNode ) { RBTreeNode *pNodeA = pNode->parent; RBTreeNode *pNodeB = pNode->right; pNode->right = pNodeB->left; pNodeB->left->parent = pNode; pNodeB->left = pNode; pNode->parent = pNodeB; if (pNode == pNodeA->left) { // 父子不同边 pNodeA->left = pNodeB; pNodeB->parent = pNodeA; } else if (pNode = pNodeA->right) { pNodeA->right = pNodeB; pNodeB->parent = pNodeA; } else // m_root == m_NIL { if (pNodeA == m_NIL) { // pNode 原本为根结点 pNodeB->parent = m_NIL; m_root = pNodeB; } } cout << "RB_Left_Rotate()\n"; } // 右旋处理函数 void CRBTree::RB_Right_Rotate( RBTreeNode *&pNode ) { RBTreeNode *pNodeA = pNode->parent; RBTreeNode *pNodeB = pNode->left; pNode->left = pNodeB->right; pNodeB->right->parent = pNode; pNodeB->right = pNode; pNode->parent = pNodeB; if (pNode == pNodeA->right) { // 父子不同边 pNodeA->right = pNodeB; pNodeB->parent = pNodeA; } else if (pNode = pNodeA->left) { pNodeA->left = pNodeB; pNodeB->parent = pNodeA; } else // m_root == m_NIL { if (pNodeA == m_NIL) { // pNodeA 原本为父结点 pNodeB->parent = m_NIL; m_root = pNodeB; } } cout << "RB_Right_Rotate()\n"; } void CRBTree::RB_Print() { if (m_root == m_NIL) { cout << "树为空!\n"; return ; } RB_Print(m_root); cout << endl; } void CRBTree::RB_Print( RBTreeNode *&pNode ) { if (pNode != m_NIL) { cout << pNode->key << "(" << pNode->color << ") "; RB_Print(pNode->left); RB_Print(pNode->right); } } void CRBTree::RB_SwapTwoNodes( RBTreeNode *&pNode1, RBTreeNode *&pNode2 ) { int t = pNode1->key; pNode1->key = pNode2->key; pNode2->key = t; } void CRBTree::RB_EmptyTree( RBTreeNode *&pNode ) { if (pNode != m_NIL) { RB_EmptyTree(pNode->left); RB_EmptyTree(pNode->right); delete pNode; } }
测试文件
////////////////////////////////// ////////////////////////// #include <iostream> #include "RBTree.h" #include <Windows.h> #include <ctime> using namespace std; void time_Test(); void Fun_Test(); int main() { cout << "红黑树RBTree测试程序 !\n"; Fun_Test(); return 0; } void Fun_Test() { CRBTree tree; tree.RB_InitLeafNode(); tree.RB_Insert(10); tree.RB_Insert(14); tree.RB_Insert(4); tree.RB_Insert(12); tree.RB_Insert(11); tree.RB_Insert(13); tree.RB_Insert(7); tree.RB_Insert(16); tree.RB_Print(); tree.RB_Delete(14); tree.RB_Delete(10); Sleep(1000); tree.RB_Print(); } void time_Test() { CRBTree tree; clock_t t_insert, t_print, t_find; int nArrNodes[50000]; tree.RB_InitLeafNode(); srand((unsigned)time(NULL)); // srand(0); t_insert = clock(); for (int i = 0; i < 50000; i++) { nArrNodes[i] = rand()%10000000 +1; while (1) { if (tree.RB_Find(nArrNodes[i]) == NULL) { tree.RB_Insert(nArrNodes[i]); break; } else nArrNodes[i] = rand()%10000000 +1; } } t_insert = clock() - t_insert; t_print = clock(); tree.RB_Print(); t_print = clock() - t_print; t_find = clock(); tree.RB_Find(32725); t_find = clock() - t_find; cout << "The tree nodes count is: " << tree.RB_GetSize() << endl; cout << "Insert data need time: " << t_insert << "ms." << endl; cout << "Print data need time: " << t_print << "ms." << endl; cout << "Find one data need time: " << t_find << "ms." << endl; }