25 #include "ndCoreStdafx.h"
29 #include "ndClassAlloc.h"
30 #include "ndContainersAlloc.h"
52 D_CORE_API
void RemoveAllLow ();
58 D_CORE_API
inline void Initdata (
ndRedBackNode*
const parent);
59 D_CORE_API
inline void SetColor (REDBLACK_COLOR color);
60 D_CORE_API REDBLACK_COLOR GetColor ()
const;
61 D_CORE_API ndUnsigned32 IsInTree ()
const;
62 D_CORE_API
inline void SetInTreeFlag (ndUnsigned32 flag);
64 D_CORE_API
void RemoveAll ();
76 ndUnsigned32 m_color : 1;
77 ndUnsigned32 m_inTree : 1;
80 template<
class OBJECT,
class KEY,
class allocator = ndContainersAlloc<OBJECT> >
92 ndNode (
const OBJECT &info,
const KEY &key,
ndNode* parentNode)
104 return (
ndNode* )ndRedBackNode::m_left;
109 return (
ndNode* )ndRedBackNode::m_right;
114 return (
ndNode* )ndRedBackNode::m_parent;
117 void SetLeft (
ndNode*
const node)
119 ndRedBackNode::m_left = node;
122 void SetRight (
ndNode*
const node)
124 ndRedBackNode::m_right = node;
127 void SetParent (
ndNode*
const node)
129 ndRedBackNode::m_parent = node;
133 const KEY& GetKey()
const
143 const OBJECT& GetInfo()
const
151 friend class ndTree<OBJECT, KEY, allocator>;
169 m_ptr = m_tree->Minimum();
174 m_ptr = m_tree->Maximum();
177 void Set (
ndNode*
const node)
182 operator ndInt32()
const
184 return m_ptr !=
nullptr;
190 m_ptr = m_ptr->Next();
193 void operator++ (ndInt32)
196 m_ptr = m_ptr->Next();
202 m_ptr = m_ptr->Prev();
205 void operator-- (ndInt32)
208 m_ptr = m_ptr->Prev();
211 OBJECT &operator* ()
const
213 return ((
ndNode*)m_ptr)->GetInfo();
225 return tmp ? tmp->GetKey() : KEY();
241 operator ndInt32()
const;
242 ndInt32 GetCount()
const;
248 ndNode* Find (
const KEY& key)
const;
249 ndNode* FindGreater (
const KEY& key)
const;
250 ndNode* FindLessEqual(
const KEY& key)
const;
251 ndNode* FindGreaterEqual (
const KEY& key)
const;
252 ndNode* FindCreate(
const KEY& key,
bool& wasFound);
254 ndNode* GetNodeFromInfo (OBJECT &info)
const;
256 ndNode* Insert(
const KEY& key);
258 ndNode* Insert(
const OBJECT &element,
const KEY& key);
259 ndNode* Insert (
const OBJECT &element,
const KEY& key,
bool& wasFound);
261 ndNode* Replace (OBJECT &element,
const KEY& key);
262 ndNode* ReplaceKey (
const KEY& oldKey,
const KEY& newKey);
263 ndNode* ReplaceKey (
ndNode*
const node,
const KEY& key);
266 void Remove (
const KEY& key);
267 void Remove (
ndNode*
const node);
269 void Unlink (
ndNode*
const node);
270 void SwapInfo (
ndTree& tree);
272 bool SanityCheck ()
const;
274 static void FlushFreeList()
276 allocator::FlushFreeList(
sizeof(
ndNode));
286 ndInt32 CompareKeys (
const KEY &key0,
const KEY &key1)
const;
287 bool SanityCheck (ndNode*
const ptr, ndInt32 height)
const;
292 inline ndRedBackNode::ndRedBackNode (
ndRedBackNode*
const parent)
297 inline void ndRedBackNode::Initdata (
ndRedBackNode*
const parent)
300 SetInTreeFlag (
true);
306 inline void ndRedBackNode::SetColor (ndRedBackNode::REDBLACK_COLOR color)
311 inline ndRedBackNode::REDBLACK_COLOR ndRedBackNode::GetColor ()
const
313 return REDBLACK_COLOR (m_color);
316 inline void ndRedBackNode::SetInTreeFlag (ndUnsigned32 flag)
321 inline ndUnsigned32 ndRedBackNode::IsInTree ()
const
326 template<
class OBJECT,
class KEY,
class allocator>
334 template<
class OBJECT,
class KEY,
class allocator>
340 template<
class OBJECT,
class KEY,
class allocator>
343 return m_head !=
nullptr;
346 template<
class OBJECT,
class KEY,
class allocator>
352 template<
class OBJECT,
class KEY,
class allocator>
355 return m_head ? (ndNode* )m_head->Minimum() :
nullptr;
358 template<
class OBJECT,
class KEY,
class allocator>
361 return m_head ? (ndNode* )m_head->Maximum() :
nullptr;
364 template<
class OBJECT,
class KEY,
class allocator>
370 template<
class OBJECT,
class KEY,
class allocator>
373 if (m_head ==
nullptr)
378 ndNode* ptr = m_head;
379 while (ptr !=
nullptr)
381 if (key < ptr->m_key)
383 ndAssert (CompareKeys (ptr->m_key, key) == -1) ;
384 ptr = ptr->GetLeft();
386 else if (key > ptr->m_key)
388 ndAssert (CompareKeys (ptr->m_key, key) == 1) ;
389 ptr = ptr->GetRight();
393 ndAssert (CompareKeys (ptr->m_key, key) == 0) ;
400 template<
class OBJECT,
class KEY,
class allocator>
403 ndNode*
const node = (ndNode* ) &info;
404 ndInt64 offset = ((
char*) &node->m_info) - ((
char *) node);
405 ndNode*
const retnode = (ndNode* ) (((
char *) node) - offset);
407 ndAssert (retnode->IsInTree ());
408 ndAssert (&retnode->GetInfo () == &info);
409 return (retnode->IsInTree ()) ? retnode :
nullptr;
412 template<
class OBJECT,
class KEY,
class allocator>
415 if (m_head ==
nullptr)
420 ndNode* prev =
nullptr;
421 ndNode* ptr = m_head;
423 while (ptr !=
nullptr)
425 if (key < ptr->m_key)
428 ptr = ptr->GetLeft();
432 ptr = ptr->GetRight();
436 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
439 Iterator iter (*
this);
440 for (iter.Begin(); iter.GetNode() != prev; iter ++)
442 KEY key1 = iter.GetKey();
443 ndAssert (key1 <= key);
445 for (; iter.GetNode(); iter ++)
447 KEY key1 = iter.GetKey();
448 ndAssert (key1 > key);
453 return (ndNode* )prev;
456 template<
class OBJECT,
class KEY,
class allocator>
459 if (m_head ==
nullptr)
464 ndNode* prev =
nullptr;
465 ndNode* ptr = m_head;
467 while (ptr !=
nullptr)
469 if (key == ptr->m_key)
473 if (key < ptr->m_key)
476 ptr = ptr->GetLeft();
480 ptr = ptr->GetRight();
484 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
487 Iterator iter (*
this);
488 for (iter.Begin(); iter.GetNode() != prev; iter ++)
490 KEY key1 = iter.GetKey();
491 ndAssert (key1 <= key);
493 for (; iter.GetNode(); iter ++)
495 KEY key1 = iter.GetKey();
496 ndAssert (key1 >= key);
501 return (ndNode* )prev;
504 template<
class OBJECT,
class KEY,
class allocator>
507 if (m_head ==
nullptr)
512 ndNode* prev =
nullptr;
513 ndNode* ptr = m_head;
515 while (ptr !=
nullptr)
517 if (key == ptr->m_key)
522 if (key < ptr->m_key)
524 ptr = ptr->GetLeft();
529 ptr = ptr->GetRight();
534 #ifdef __ENABLE_DG_CONTAINERS_SANITY_CHECK
537 Iterator iter (*
this);
538 for (iter.End(); iter.GetNode() != prev; iter --)
540 KEY key1 = iter.GetKey();
541 ndAssert (key1 >= key);
543 for (; iter.GetNode(); iter --)
545 KEY key1 = iter.GetKey();
546 ndAssert (key1 < key);
551 return (ndNode* )prev;
554 template<
class OBJECT,
class KEY,
class allocator>
557 ndNode* parent =
nullptr;
558 ndNode* ptr = m_head;
560 while (ptr !=
nullptr)
564 if (key < ptr->m_key)
566 ndAssert (CompareKeys (ptr->m_key, key) == -1) ;
568 ptr = ptr->GetLeft();
570 else if (key > ptr->m_key)
572 ndAssert (CompareKeys (ptr->m_key, key) == 1) ;
574 ptr = ptr->GetRight();
578 ndAssert (CompareKeys (ptr->m_key, key) == 0) ;
586 ptr =
new ndNode (element, key, parent);
595 parent->m_left = ptr;
599 parent->m_right = ptr;
603 ndNode**
const headPtr = (ndNode**) &m_head;
608 template<
class OBJECT,
class KEY,
class allocator>
611 ndNode* parent =
nullptr;
612 ndNode* ptr = m_head;
614 while (ptr !=
nullptr)
617 if (key < ptr->m_key)
619 ndAssert(CompareKeys(ptr->m_key, key) == -1);
621 ptr = ptr->GetLeft();
623 else if (key > ptr->m_key)
625 ndAssert(CompareKeys(ptr->m_key, key) == 1);
627 ptr = ptr->GetRight();
631 ndAssert(CompareKeys(ptr->m_key, key) == 0);
639 ptr =
new ndNode(key, parent);
648 parent->m_left = ptr;
652 parent->m_right = ptr;
656 ndNode**
const headPtr = (ndNode**)&m_head;
661 template<
class OBJECT,
class KEY,
class allocator>
666 ndNode*
const node = Insert (element, key, foundState);
674 template<
class OBJECT,
class KEY,
class allocator>
678 return Insert(element, key);
681 template<
class OBJECT,
class KEY,
class allocator>
685 ndNode* ptr = m_head;
686 ndNode* parent =
nullptr;
687 while (ptr !=
nullptr)
691 if (key < ptr->m_key)
693 ndAssert (CompareKeys (ptr->m_key, key) == -1) ;
695 ptr = ptr->GetLeft();
697 else if (key > ptr->m_key)
699 ndAssert (CompareKeys (ptr->m_key, key) == 1) ;
701 ptr = ptr->GetRight();
705 ndAssert (CompareKeys (ptr->m_key, key) == 0) ;
714 ptr->Initdata (parent);
724 parent->m_left = ptr;
728 parent->m_right = ptr;
732 ndNode**
const headPtr = (ndNode**) &m_head;
737 template<
class OBJECT,
class KEY,
class allocator>
740 ndNode* parent =
nullptr;
741 ndNode* ptr = m_head;
744 while (ptr !=
nullptr)
749 val = CompareKeys (ptr->m_key, key);
752 ptr->m_info = element;
757 ptr = ptr->GetLeft();
761 ptr = ptr->GetRight();
765 ptr =
new ndNode (element, key, parent);
774 parent->m_left = ptr;
778 parent->m_right = ptr;
782 ndNode**
const headPtr = (ndNode**) &m_head;
787 template<
class OBJECT,
class KEY,
class allocator>
791 ndNode*
const ptr = Insert (node, key);
796 template<
class OBJECT,
class KEY,
class allocator>
799 ndNode*
const node = Find (oldKey);
800 return node ? ReplaceKey (node, newKey) : nullptr;
803 template<
class OBJECT,
class KEY,
class allocator>
808 ndNode**
const headPtr = (ndNode**) &m_head;
810 ndAssert (!Find (node->GetKey()));
813 template<
class OBJECT,
class KEY,
class allocator>
817 ndNode**
const headPtr = (ndNode**) &m_head;
821 template<
class OBJECT,
class KEY,
class allocator>
825 ndNode*
const node = Find (key);
832 template<
class OBJECT,
class KEY,
class allocator>
838 m_head->RemoveAll ();
843 template<
class OBJECT,
class KEY,
class allocator>
846 return SanityCheck (m_head, 0);
849 template<
class OBJECT,
class KEY,
class allocator>
857 if (!ptr->IsInTree())
864 if (CompareKeys (ptr->m_key, ptr->GetLeft()->m_key) > 0)
872 if (CompareKeys (ptr->m_key, ptr->GetRight()->m_key) < 0)
878 if (ptr->GetColor() == ndNode::BLACK)
882 else if (!((!ptr->m_left || (ptr->m_left->GetColor() == ndNode::BLACK)) &&
883 (!ptr->m_right || (ptr->m_right->GetColor() == ndNode::BLACK))))
888 if (!ptr->m_left && !ptr->m_right)
891 for (ndNode* x = ptr; x; x = x->GetParent())
893 if (x->GetColor() == ndNode::BLACK)
904 if (ptr->m_left && !SanityCheck (ptr->GetLeft(), height))
909 if (ptr->m_right && !SanityCheck (ptr->GetRight(), height))
916 template<
class OBJECT,
class KEY,
class allocator>
930 template<
class OBJECT,
class KEY,
class allocator>
933 ndSwap (m_head, tree.m_head);
934 ndSwap (m_count, tree.m_count);