5 // Created by Terrin Eager on 7/9/12.
7 // based on rbtree.h but converted to C++
8 // ll from http://www.cs.princeton.edu/~rs/talks/LLRB/RedBlack.pdf
10 #ifndef __TestTB__LLRBTree__
11 #define __TestTB__LLRBTree__
15 #include <sys/socket.h>
19 template <class KeyType>
23 CRBNode() {m_bIsRed = true; m_rbLeft = m_rbRight = NULL;};
26 inline virtual BJ_COMPARE Compare(KeyType* pKey) = 0; // Key values are equal
28 inline virtual void CopyNode(CRBNode* pSource) = 0;
29 inline virtual void Init()=0;
30 inline virtual void Clear()=0;
32 CRBNode* GetMinNode();
33 CRBNode* GetMaxNode();
36 inline CRBNode* RotateNodeLeft();
37 inline CRBNode* RotateNodeRight();
40 CRBNode* AddRecord(CRBNode* pNewRecord);
48 CRBNode* MoveRedLeft();
49 CRBNode* MoveRedRight();
51 void CallBack(int(*callback)(const void*, const void*),void* pParam);
64 template <class KeyType, class NodeType>
70 virtual ~CLLRBTree() { if (m_Root) delete m_Root;};
72 NodeType* Find(KeyType* pKey);
74 NodeType* FindwithAddRecord(KeyType* pKey);
75 NodeType* AddRecord(KeyType* pKey);
76 void RemoveRecord(KeyType* pKey);
78 NodeType* GetRoot() { return m_Root;};
79 void ClearAll() { delete m_Root; m_Root = NULL;};
84 NodeType* GetMinNode();
85 NodeType* GetMaxNode();
87 NodeType* deleteMin(NodeType* pRecord);
91 NodeType* RemoveRecord(NodeType* pRecord,KeyType* pKey);
93 virtual NodeType* newNode(KeyType* pKey) { return new NodeType(pKey);}
94 virtual void freeNode(NodeType * pNode){ delete pNode;};
104 template<class KeyType>
105 CRBNode<KeyType>::~CRBNode()
117 template<class KeyType>
118 CRBNode<KeyType>* CRBNode<KeyType>::RotateNodeLeft()
120 CRBNode<KeyType>* pTemp = m_rbRight;
121 m_rbRight = pTemp->m_rbLeft;
122 pTemp->m_rbLeft = this;
123 pTemp->m_bIsRed = pTemp->m_rbLeft->m_bIsRed;
124 pTemp->m_rbLeft->m_bIsRed = 1;
130 template<class KeyType>
131 CRBNode<KeyType>* CRBNode<KeyType>::RotateNodeRight()
133 CRBNode<KeyType>* pTemp = m_rbLeft;
134 m_rbLeft = pTemp->m_rbRight;
135 pTemp->m_rbRight = this;
136 pTemp->m_bIsRed = pTemp->m_rbRight->m_bIsRed;
137 pTemp->m_rbRight->m_bIsRed = 1;
142 template<class KeyType>
143 BJ_UINT64 CRBNode<KeyType>::GetCount()
147 Num += m_rbLeft->GetCount();
149 Num += m_rbRight->GetCount();
155 template<class KeyType>
156 void CRBNode<KeyType>::FlipColor()
158 m_bIsRed = !m_bIsRed;
160 m_rbLeft->m_bIsRed = !m_rbLeft->m_bIsRed;
162 m_rbRight->m_bIsRed = !m_rbRight->m_bIsRed;
166 template<class KeyType>
167 CRBNode<KeyType>* CRBNode<KeyType>::Fixup()
169 // fix the tree balance
170 CRBNode<KeyType>* pNode = this;
172 if (m_rbRight && m_rbRight->m_bIsRed) // fix right leaning reds on the way up
173 pNode = RotateNodeLeft();
175 if (pNode && pNode->m_rbLeft && pNode->m_rbLeft->m_bIsRed && pNode->m_rbLeft->m_rbLeft && pNode->m_rbLeft->m_rbLeft->m_bIsRed) // fix two reds in a row on the way up
176 pNode = RotateNodeRight();
178 if (pNode && pNode->m_rbRight && pNode->m_rbRight->m_bIsRed && pNode->m_rbLeft && pNode->m_rbLeft->m_bIsRed) //split 4-nodes on the way up
184 template<class KeyType>
185 CRBNode<KeyType>* CRBNode<KeyType>::MoveRedLeft()
187 CRBNode* pNode = this;
190 if (m_rbRight && m_rbRight->m_rbLeft && m_rbRight->m_rbLeft->m_bIsRed)
192 m_rbRight = m_rbRight->RotateNodeRight();
193 pNode = RotateNodeLeft();
200 template<class KeyType>
201 CRBNode<KeyType>* CRBNode<KeyType>::MoveRedRight()
203 CRBNode* pNode = this;
206 if (m_rbLeft && m_rbLeft->m_rbLeft && m_rbLeft->m_rbLeft->m_bIsRed)
208 pNode = RotateNodeRight();
215 template<class KeyType>
216 CRBNode<KeyType>* CRBNode<KeyType>::AddRecord(CRBNode* pNewRecord)
219 switch (Compare(&pNewRecord->m_Key))
223 m_rbRight = m_rbRight->AddRecord(pNewRecord);
225 m_rbRight = pNewRecord;
230 m_rbLeft = m_rbLeft->AddRecord(pNewRecord);
232 m_rbLeft = pNewRecord;
236 pNewRecord->m_bIsRed = false;
237 pNewRecord->m_rbLeft = m_rbLeft;
238 m_rbLeft = pNewRecord;
242 // fix the tree balance
243 CRBNode* pRecord = this;
245 // fix the tree balance
247 if (pRecord && pRecord->m_rbRight && pRecord->m_rbRight->m_bIsRed) // fix right leaning reds on the way up
248 pRecord = pRecord->RotateNodeLeft();
250 if (pRecord && pRecord->m_rbLeft && pRecord->m_rbLeft->m_bIsRed && pRecord->m_rbLeft->m_rbLeft && pRecord->m_rbLeft->m_rbLeft->m_bIsRed) // fix two reds in a row on the way up
251 pRecord = pRecord->RotateNodeRight();
253 if (pRecord && pRecord->m_rbRight && pRecord->m_rbRight->m_bIsRed && pRecord->m_rbLeft && pRecord->m_rbLeft->m_bIsRed) //split 4-nodes on the way up
254 pRecord->FlipColor();
262 template<class KeyType>
263 CRBNode<KeyType>* CRBNode<KeyType>::GetMinNode()
265 CRBNode* pRecord = this;
266 while (pRecord && pRecord->m_rbLeft)
267 pRecord = pRecord->m_rbLeft;
271 template<class KeyType>
272 CRBNode<KeyType>* CRBNode<KeyType>::GetMaxNode()
274 CRBNode* pRecord = this;
275 while (pRecord && pRecord->m_rbRight)
276 pRecord = pRecord->m_rbRight;
281 template<class KeyType>
282 void CRBNode<KeyType>::CallBack(int(*callback)(const void*, const void*),void* pParam)
286 m_rbLeft->CallBack(callback,pParam);
288 callback(this,pParam);
291 m_rbRight->CallBack(callback,pParam);
299 template<class KeyType,class NodeType>
300 CLLRBTree<KeyType,NodeType>::CLLRBTree()
305 template<class KeyType,class NodeType>
306 NodeType* CLLRBTree<KeyType,NodeType>::Find(KeyType* pKey)
309 CRBNode<KeyType>* pNode = m_Root;
313 switch (pNode->Compare(pKey))
316 pNode = pNode->m_rbRight;
319 pNode = pNode->m_rbLeft;
322 return (NodeType*)pNode;
331 template<class KeyType,class NodeType>
332 NodeType* CLLRBTree<KeyType,NodeType>::AddRecord(KeyType* pKey)
334 NodeType* pRecord = newNode(pKey);
336 m_Root = (NodeType*) m_Root->AddRecord(pRecord);
341 m_Root->m_bIsRed = false;
346 template<class KeyType,class NodeType>
347 NodeType* CLLRBTree<KeyType,NodeType>::FindwithAddRecord(KeyType* pKey)
349 NodeType* pRecord = NULL;
351 pRecord = Find(pKey);
354 pRecord = AddRecord(pKey);
359 template<class KeyType,class NodeType>
360 void CLLRBTree<KeyType,NodeType>::RemoveRecord(KeyType* pKey)
362 m_Root = RemoveRecord(m_Root,pKey);
365 template<class KeyType,class NodeType>
366 NodeType* CLLRBTree<KeyType,NodeType>::deleteMin(NodeType* pRecord)
368 if (pRecord->m_rbLeft == NULL)
374 if (!(pRecord->m_rbLeft && pRecord->m_rbLeft->m_bIsRed) && !(pRecord->m_rbLeft && pRecord->m_rbLeft->m_rbLeft &&pRecord->m_rbLeft->m_rbLeft->m_bIsRed))
375 pRecord = (NodeType*)pRecord->MoveRedLeft();
377 pRecord->m_rbLeft = deleteMin((NodeType*)pRecord->m_rbLeft);
379 return (NodeType*)pRecord->Fixup();
382 template<class KeyType,class NodeType>
383 NodeType* CLLRBTree<KeyType,NodeType>::RemoveRecord(NodeType* pRecord,KeyType* pKey)
385 NodeType* pTempRecord = NULL;
390 if (pRecord->Compare(pKey) == BJ_LT)
392 if (!(pRecord->m_rbLeft &&pRecord->m_rbLeft->m_bIsRed) && !(pRecord->m_rbLeft && pRecord->m_rbLeft->m_rbLeft &&pRecord->m_rbLeft->m_rbLeft->m_bIsRed))
393 pRecord->MoveRedLeft();
394 pRecord = RemoveRecord((NodeType*)pRecord->m_rbLeft, pKey);
398 if (pRecord->m_rbLeft &&pRecord->m_rbLeft->m_bIsRed)
399 pRecord->RotateNodeRight();
401 if(pRecord->Compare(pKey) == BJ_EQUAL && pRecord->m_rbRight == NULL)
407 if (!(pRecord->m_rbRight && pRecord->m_rbRight->m_bIsRed) && !(pRecord->m_rbRight && pRecord->m_rbRight->m_rbLeft && pRecord->m_rbRight->m_rbLeft->m_bIsRed))
408 pRecord = (NodeType*)pRecord->MoveRedRight();
410 if (pRecord->Compare(pKey) == BJ_EQUAL)
412 pTempRecord = (NodeType*)pRecord->GetMinNode();
413 pRecord->CopyNode(pTempRecord);
414 pRecord->m_rbRight = deleteMin((NodeType*)pRecord->m_rbRight);
418 pRecord->m_rbRight = RemoveRecord((NodeType*)pRecord->m_rbRight, pKey);
421 return pRecord?(NodeType*)pRecord->Fixup():NULL;
427 template<class KeyType,class NodeType>
428 BJ_UINT64 CLLRBTree<KeyType,NodeType>::GetCount()
431 return m_Root->GetCount();
436 template<class KeyType,class NodeType>
437 NodeType* CLLRBTree<KeyType,NodeType>::GetMinNode()
440 return m_Root->GetMinNode();
446 template<class KeyType,class NodeType>
447 NodeType* CLLRBTree<KeyType,NodeType>::GetMaxNode()
450 return m_Root->GetMaxNode();
460 #endif /* defined(__TestTB__LLRBTree__) */