理论参考:
维基百科中的红黑树算法介绍的很详细,下面是C++代码实现
- #ifndef _FRAME_RBTREE_H_
- #define _FRAME_RBTREE_H_
- #include <stdint.h>
- #include <new>
- #define S_OK 0
- #define E_CONTAIN_FULL 0x80000001
- #define E_NOT_FOUND 0x80000002
- template <typename Key, typename Value, uint32_t DEFAULT_ADD = 1024>
- class CRBTree
- {
- protected:
- enum Color
- {
- enmColor_Red,
- enmColor_Black,
- };
- public:
- class Node
- {
- public:
- Key nKey;
- Value value;
- private:
- Node *pParent;
- Node *pLeft;
- Node *pRight;
- Color nColor;
- friend class CRBTree;
- Node()
- {
- pParent = NULL;
- pLeft = NULL;
- pRight = NULL;
- nColor = enmColor_Red;
- }
- };
- public:
- CRBTree()
- {
- m_pRoot = NULL;
- m_pHead = NULL;
- m_pMin = NULL;
- m_nSize = 0;
- m_pBuffer = NULL;
- }
- virtual ~CRBTree()
- {
- Clear();
- while(NULL != m_pBuffer)
- {
- uint8_t *pBuffer = m_pBuffer;
- m_pBuffer = *(uint8_t**)m_pBuffer;
- delete pBuffer;
- }
- }
- protected:
- Node* Pop()
- {
- if (NULL == m_pHead)
- {
- Reserve(GetCapacity() + DEFAULT_ADD);
- }
- ++m_nSize;
- Node *pNode = m_pHead;
- m_pHead = pNode->pParent;
- return new(pNode)Node();
- }
- void Push(Node *pNode)
- {
- --m_nSize;
- pNode->~Node();
- pNode->pParent = m_pHead;
- m_pHead = pNode;
- }
- public:
- int32_t Insert(const Key nKey, const Value &value)
- {
- Node *pNode = Pop();
- if (NULL == pNode)
- {
- return E_CONTAIN_FULL;
- }
- pNode->nKey = nKey;
- pNode->value = value;
- if ((NULL == m_pMin) || (m_pMin->nKey >= pNode->nKey))
- {
- m_pMin = pNode;
- }
- Node *pParent = FindSite(m_pRoot, nKey);
- if (NULL == pParent)
- {
- m_pRoot = pNode;
- pNode->nColor = enmColor_Black;
- return S_OK;
- }
- pNode->pParent = pParent;
- if (pParent->nKey >= nKey)
- {
- pParent->pLeft = pNode;
- }
- else
- {
- pParent->pRight = pNode;
- }
- InsertRebalance(pNode);
- return S_OK;
- }
- int32_t Delete(const Key nKey)
- {
- Node *pNode = FindNode(nKey);
- if (NULL == pNode)
- {
- return S_OK;
- }
- if (m_pMin == pNode)
- {
- m_pMin = (NULL == pNode->pRight) ? pNode->pParent : FindSite(pNode->pRight, pNode->nKey);
- }
- if ((NULL != pNode->pLeft)
- && (NULL != pNode->pRight))
- {
- //替换
- Node *pRMinNode = FindSite(pNode->pRight, nKey);
- Key nKey = pNode->nKey;
- Value value = pNode->value;
- pNode->nKey = pRMinNode->nKey;
- pNode->value = pRMinNode->value;
- pRMinNode->nKey = nKey;
- pRMinNode->value = value;
- pNode = pRMinNode;
- }
- if (pNode == m_pRoot)
- {
- if (NULL != pNode->pLeft)
- {
- m_pRoot = pNode->pLeft;
- m_pRoot->pParent = NULL;
- }
- else if (NULL != pNode->pRight)
- {
- m_pRoot = pNode->pRight;
- m_pRoot->pParent = NULL;
- }
- else
- {
- m_pRoot = NULL;
- }
- Push(pNode);
- return S_OK;
- }
- if (enmColor_Black == pNode->nColor)
- {
- Node *pChild = NULL;
- if (NULL != pNode->pLeft)
- {
- pChild = pNode->pLeft;
- }
- else if (NULL != pNode->pRight)
- {
- pChild = pNode->pRight;
- }
- if (NULL != pChild)
- {
- pNode->nColor = pChild->nColor;
- }
- DeleteRebalance(pNode);
- if (NULL != pChild)
- {
- pChild->nColor = pNode->nColor;
- }
- }
- //删除节点
- Node *pParent = pNode->pParent;
- if (NULL != pNode->pLeft)
- {
- pNode->pLeft->pParent = pParent;
- if (pNode == pParent->pLeft)
- {
- pParent->pLeft = pNode->pLeft;
- }
- else
- {
- pParent->pRight = pNode->pLeft;
- }
- }
- else if (NULL != pNode->pRight)
- {
- pNode->pRight->pParent = pParent;
- if (pNode == pParent->pLeft)
- {
- pParent->pLeft = pNode->pRight;
- }
- else
- {
- pParent->pRight = pNode->pRight;
- }
- }
- else
- {
- if (pNode == pParent->pLeft)
- {
- pParent->pLeft = NULL;
- }
- else
- {
- pParent->pRight = NULL;
- }
- }
- Push(pNode);
- return S_OK;
- }
- int32_t Find(const Key nKey, Value &value)
- {
- Node *pNode = FindNode(nKey);
- if (NULL == pNode)
- {
- return E_NOT_FOUND;
- }
- value = pNode->value;
- return S_OK;
- }
- void Clear()
- {
- while(NULL != Begin())
- {
- Delete(Begin()->nKey);
- }
- }
- void Reserve(const uint32_t nReserveSize)
- {
- const uint32_t nCapacity = GetCapacity();
- if (nReserveSize <= nCapacity)
- {
- return;
- }
- Node arrNode[2];
- const uint64_t nSize = (uint64_t)&arrNode[1] - (uint64_t)&arrNode[0];
- const uint32_t nBlock = (nReserveSize - nCapacity + DEFAULT_ADD - 1) / DEFAULT_ADD;
- for (uint32_t i = 0; i < nBlock; ++i)
- {
- uint8_t *pBuffer = new uint8_t[DEFAULT_ADD * nSize + sizeof(uint8_t*)];
- *(uint8_t**)pBuffer = m_pBuffer;
- m_pBuffer = pBuffer;
- for (uint32_t j = 0; j < DEFAULT_ADD; ++j)
- {
- Node *pNode = (Node*)(pBuffer + sizeof(uint8_t*) + j * nSize);
- pNode->pParent = m_pHead;
- m_pHead = pNode;
- }
- }
- }
- const Node* Begin()
- {
- return m_pMin;
- }
- const Node* Next(const Node *pNode)
- {
- if (NULL == pNode)
- {
- return NULL;
- }
- else if (NULL != pNode->pRight)
- {
- return FindSite(pNode->pRight, pNode->nKey);
- }
- else if (NULL != pNode->pParent)
- {
- while ((NULL != pNode->pParent) && (pNode == pNode->pParent->pRight))
- {
- pNode = pNode->pParent;
- }
- return pNode->pParent;
- }
- return NULL;
- }
- uint32_t GetSize()
- {
- return m_nSize;
- }
- uint32_t GetCapacity()
- {
- uint32_t nCapacity = 0;
- uint8_t *pBuffer = m_pBuffer;
- while(NULL != pBuffer)
- {
- pBuffer = *(uint8_t**)pBuffer;
- nCapacity += DEFAULT_ADD;
- }
- return nCapacity;
- }
- protected:
- Node* FindSite(Node *pNode, const Key nKey)
- {
- if (NULL == pNode)
- {
- return NULL;
- }
- while(true)
- {
- if (pNode->nKey >= nKey)
- {
- if (NULL == pNode->pLeft)
- {
- return pNode;
- }
- pNode = pNode->pLeft;
- continue;
- }
- else
- {
- if (NULL == pNode->pRight)
- {
- return pNode;
- }
- pNode = pNode->pRight;
- continue;
- }
- }
- return NULL;
- }
- Node* FindNode(const Key nKey)
- {
- Node *pNode = m_pRoot;
- if (NULL == pNode)
- {
- return NULL;
- }
- while (true)
- {
- if (pNode->nKey == nKey)
- {
- return pNode;
- }
- else if (pNode->nKey > nKey)
- {
- if (NULL == pNode->pLeft)
- {
- return NULL;
- }
- else
- {
- pNode = pNode->pLeft;
- continue;
- }
- }
- else
- {
- if (NULL == pNode->pRight)
- {
- return NULL;
- }
- else
- {
- pNode = pNode->pRight;
- continue;
- }
- }
- }
- return NULL;
- }
- void InsertRebalance(Node *pNode)
- {
- while(true)
- {
- //case 1
- if (NULL == pNode->pParent)
- {
- m_pRoot = pNode;
- pNode->nColor = enmColor_Black;
- return;
- }
- //case 2
- Node *pParent = pNode->pParent;
- if (enmColor_Black == pParent->nColor)
- {
- return;
- }
- //case 3
- Node *pGrandParent = pParent->pParent;
- Node *pUncle = Uncle(pNode);
- if ((NULL != pUncle) && (enmColor_Red == pUncle->nColor))
- {
- pParent->nColor = enmColor_Black;
- pUncle->nColor = enmColor_Black;
- pGrandParent->nColor = enmColor_Red;
- pNode = pGrandParent;
- continue;
- }
- //case 4
- if ((pNode == pParent->pRight) && (pParent == pGrandParent->pLeft))
- {
- RotateLeft(pParent);
- pNode = pNode->pLeft;
- }
- else if ((pNode == pParent->pLeft) && (pParent == pGrandParent->pRight))
- {
- RotateRight(pParent);
- pNode = pNode->pRight;
- }
- //case 5
- pParent = pNode->pParent;
- pGrandParent = pParent->pParent;
- pParent->nColor = enmColor_Black;
- pGrandParent->nColor = enmColor_Red;
- if ((pNode == pParent->pLeft) && (pParent == pGrandParent->pLeft))
- {
- RotateRight(pGrandParent);
- }
- else
- {
- RotateLeft(pGrandParent);
- }
- break;
- }
- while((NULL != m_pRoot) && (NULL != m_pRoot->pParent))
- {
- m_pRoot = m_pRoot->pParent;
- }
- }
- void DeleteRebalance(Node* pNode)
- {
- if (enmColor_Red == pNode->nColor)
- {
- pNode->nColor = enmColor_Black;
- return;
- }
- while(true)
- {
- //case 1
- if (NULL == pNode->pParent)
- {
- break;
- }
- //case 2
- Node *pParent = pNode->pParent;
- //兄弟节点不可能是空节点
- Node *pBrother = Brother(pNode);
- if (enmColor_Red == pBrother->nColor)
- {
- pParent->nColor = enmColor_Red;
- pBrother->nColor = enmColor_Black;
- if (pNode == pParent->pLeft)
- {
- RotateLeft(pParent);
- }
- else
- {
- RotateRight(pParent);
- }
- //旋转后兄弟节点位置发生变化
- pBrother = Brother(pNode);
- if (NULL == pBrother)
- {
- pParent->nColor = enmColor_Black;
- break;
- }
- }
- //case 3
- if ((enmColor_Black == pParent->nColor)
- && SelfAndSonAllBlack(pBrother))
- {
- pBrother->nColor = enmColor_Red;
- pNode = pParent;
- continue;
- }
- //case 4
- if ((enmColor_Red == pParent->nColor)
- && SelfAndSonAllBlack(pBrother))
- {
- pBrother->nColor = enmColor_Red;
- pParent->nColor = enmColor_Black;
- break;
- }
- //case 5
- if (enmColor_Black == pBrother->nColor)
- {
- if ((pNode == pParent->pLeft)
- && (NULL != pBrother->pLeft)
- && (enmColor_Red == pBrother->pLeft->nColor))
- {
- if ((NULL == pBrother->pRight)
- || (enmColor_Black == pBrother->pRight->nColor))
- {
- pBrother->nColor = enmColor_Red;
- pBrother->pLeft->nColor = enmColor_Black;
- RotateRight(pParent->pRight);
- }
- }
- else if ((pNode == pParent->pRight)
- && (NULL != pBrother->pRight)
- && (enmColor_Red == pBrother->pRight->nColor))
- {
- if ((NULL == pBrother->pLeft)
- || (enmColor_Black == pBrother->pLeft->nColor))
- {
- pBrother->nColor = enmColor_Red;
- pBrother->pRight->nColor = enmColor_Black;
- RotateLeft(pParent->pLeft);
- }
- }
- //旋转后兄弟节点位置发生变化
- pBrother = Brother(pNode);
- }
- //case 6
- pBrother->nColor = pParent->nColor;
- pParent->nColor = enmColor_Black;
- if (pNode == pParent->pLeft)
- {
- if (NULL != pBrother->pRight)
- {
- pBrother->pRight->nColor = enmColor_Black;
- }
- RotateLeft(pParent);
- }
- else
- {
- if (NULL != pBrother->pLeft)
- {
- pBrother->pLeft->nColor = enmColor_Black;
- }
- RotateRight(pParent);
- }
- break;
- }
- while((NULL != m_pRoot) && (NULL != m_pRoot->pParent))
- {
- m_pRoot = m_pRoot->pParent;
- }
- }
- Node* Uncle(const Node *pNode)
- {
- Node *pParent = pNode->pParent;
- if ((NULL == pParent) || (NULL == pParent->pParent))
- {
- return NULL;
- }
- Node *pGrandParent = pParent->pParent;
- if (pParent == pGrandParent->pLeft)
- {
- return (NULL == pGrandParent->pRight) ? NULL : pGrandParent->pRight;
- }
- return (NULL == pGrandParent->pLeft) ? NULL : pGrandParent->pLeft;
- }
- Node* Brother(const Node *pNode)
- {
- if (NULL == pNode->pParent)
- {
- return NULL;
- }
- Node *pParent = pNode->pParent;
- if (pNode == pParent->pLeft)
- {
- return (NULL == pParent->pRight) ? NULL : pParent->pRight;
- }
- return (NULL == pParent->pLeft) ? NULL : pParent->pLeft;
- }
- void RotateLeft(Node *pNode)
- {
- Node *pRSon = pNode->pRight;
-
- if (NULL != pNode->pParent)
- {
- Node *pParent = pNode->pParent;
- (pNode == pParent->pLeft) ? pParent->pLeft = pNode->pRight : pParent->pRight = pNode->pRight;
- }
- pRSon->pParent = pNode->pParent;
- pNode->pParent = pNode->pRight;
- pNode->pRight = pRSon->pLeft;
- pRSon->pLeft = pNode;
- if (NULL != pNode->pRight)
- {
- pNode->pRight->pParent = pNode;
- }
- }
- void RotateRight(Node *pNode)
- {
- Node *pLSon = pNode->pLeft;
- if (NULL != pNode->pParent)
- {
- Node *pParent = pNode->pParent;
- (pNode == pParent->pLeft) ? pParent->pLeft = pNode->pLeft: pParent->pRight = pNode->pLeft;
- }
- pLSon->pParent = pNode->pParent;
- pNode->pParent = pNode->pLeft;
- pNode->pLeft = pLSon->pRight;
- pLSon->pRight = pNode;
- if (NULL != pNode->pLeft)
- {
- pNode->pLeft->pParent = pNode;
- }
- }
- bool SelfAndSonAllBlack(const Node *pNode)
- {
- if (enmColor_Black != pNode->nColor)
- {
- return false;
- }
- if ((NULL != pNode->pLeft)
- && (enmColor_Black != pNode->pLeft->nColor))
- {
- return false;
- }
- if ((NULL != pNode->pRight)
- && (enmColor_Black != pNode->pRight->nColor))
- {
- return false;
- }
- return true;
- }
- protected:
- Node *m_pRoot;
- Node *m_pHead;
- Node *m_pMin;
- uint32_t m_nSize;
- uint8_t *m_pBuffer;
- };
- #endif
下面是测试代码,在linux平台环境下测试通过
- #include <stdlib.h>
- #include <iostream>
- #include "frame_rbtree.h"
- using namespace std;
- #define COUT(x) \
- do { cout << #x << "=" << x << endl; } while(false)
- typedef CRBTree<uint32_t, uint32_t, 16> RBTree;
- enum
- {
- //enmKeySize = 512,
- };
- class A
- {
- public:
- A()
- {
- COUT(__FUNCTION__);
- }
- ~A()
- {
- COUT(__FUNCTION__);
- }
- };
- typedef CRBTree<uint32_t, uint32_t, 16> RBTree;
- typedef CRBTree<uint32_t, A, 16> ARBTree;
- int32_t main(const int32_t argc, const char** argv)
- {
- uint32_t enmKeySize = (uint32_t)atoi(argv[1]);
- COUT(enmKeySize);
- /*
- A a;
- ARBTree *Atree = new ARBTree();
- for (uint32_t i = 0; i < enmKeySize; ++i)
- {
- Atree->Insert(i, a);
- }
- for (const ARBTree::Node *pNode = Atree->Begin(); NULL != pNode; pNode = Atree->Next(pNode))
- {
- COUT(pNode->nKey);
- }
- for (uint32_t i = 0; i < enmKeySize; ++i)
- {
- Atree->Delete(i);
- }
- Atree->Reserve(100);
- COUT(Atree->GetSize());
- COUT(Atree->GetCapacity());
- delete Atree;
- return 0;
- */
- uint32_t *arrKey = new uint32_t[enmKeySize];
- for (uint32_t i = 0; i < enmKeySize; ++i)
- {
- arrKey[i] = i;
- }
- srand(time(NULL));
- for (uint32_t i = 0; i < enmKeySize; ++i)
- {
- uint32_t nRand = rand() % enmKeySize;
- uint32_t nTmp = arrKey[nRand];
- arrKey[nRand] = arrKey[i];
- arrKey[i] = nTmp;
- }
- RBTree *tree = new RBTree();
- for (uint32_t i = 0; i < enmKeySize; ++i)
- {
- tree->Insert(arrKey[i], i);
- //tree->Insert(i, i);
- }
- for (uint32_t i = 0; i < enmKeySize; i++)
- {
- tree->Delete(i);
- }
- for (uint32_t i = enmKeySize; i < enmKeySize * 2; ++i)
- {
- tree->Insert(i, i);
- }
- for (uint32_t i = 0; i < enmKeySize * 2; i += 10)
- {
- tree->Delete(i);
- }
- for (uint32_t i = 0; i < enmKeySize * 2; i += 10)
- {
- tree->Insert(i, i);
- }
- for (uint32_t i = 0; i < enmKeySize * 2; i += 10)
- {
- tree->Insert(0, 0);
- tree->Insert(enmKeySize * 2, enmKeySize * 2);
- }
- for (const RBTree::Node *pNode = tree->Begin(); NULL != pNode; pNode = tree->Next(pNode))
- {
- printf("Key=%d, Value=%d\n", pNode->nKey, pNode->value);
- }
- COUT(tree->GetSize());
- COUT(tree->GetCapacity());
- return 0;
- }
阅读(1667) | 评论(0) | 转发(0) |