You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
4.2 KiB
197 lines
4.2 KiB
/***
|
|
*bintree.cpp - RTC support
|
|
*
|
|
* Copyright (c) 1998-2001, Microsoft Corporation. All rights reserved.
|
|
*
|
|
*
|
|
*Revision History:
|
|
* 07-28-98 JWM Module incorporated into CRTs (from KFrei)
|
|
* 11-03-98 KBF Removed alloca dependency for CRT independence
|
|
* 05-11-99 KBF Error if RTC support define not enabled
|
|
* 05-26-99 KBF Everything is now prefixed with _RTC_
|
|
*
|
|
****/
|
|
|
|
#ifndef _RTC
|
|
#error RunTime Check support not enabled!
|
|
#endif
|
|
|
|
#include "rtcpriv.h"
|
|
|
|
#ifdef _RTC_ADVMEM
|
|
|
|
void
|
|
_RTC_BinaryTree::BinaryNode::kill() throw()
|
|
{
|
|
if (l)
|
|
{
|
|
l->kill();
|
|
delete l;
|
|
}
|
|
if (r)
|
|
{
|
|
r->kill();
|
|
delete r;
|
|
}
|
|
delete val;
|
|
}
|
|
|
|
_RTC_Container *
|
|
_RTC_BinaryTree::get(_RTC_HeapBlock *data) throw()
|
|
{
|
|
BinaryNode *t = tree;
|
|
while (t)
|
|
{
|
|
if (t->val->contains(data))
|
|
return t->val;
|
|
|
|
if (*t->val->info() < *data)
|
|
t = t->l;
|
|
else
|
|
t = t->r;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
_RTC_Container *
|
|
_RTC_BinaryTree::add(_RTC_HeapBlock* data) throw()
|
|
{
|
|
BinaryNode *t = tree;
|
|
if (!tree)
|
|
{
|
|
tree = new BinaryNode(0,0,new _RTC_Container(data));
|
|
return tree->val;
|
|
}
|
|
for (;;)
|
|
{
|
|
if (*t->val->info() < *data)
|
|
{
|
|
// before this one
|
|
if (t->l)
|
|
t = t->l;
|
|
else
|
|
{
|
|
t->l = new BinaryNode(0,0,new _RTC_Container(data));
|
|
return t->l->val;
|
|
}
|
|
} else
|
|
{
|
|
if (t->r)
|
|
t = t->r;
|
|
else
|
|
{
|
|
t->r = new BinaryNode(0, 0, new _RTC_Container(data));
|
|
return t->r->val;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
_RTC_Container *
|
|
_RTC_BinaryTree::del(_RTC_HeapBlock *data) throw()
|
|
{
|
|
BinaryNode **prv = &tree;
|
|
while (*prv && (*prv)->val->info() != data)
|
|
{
|
|
prv = (*(*prv)->val->info() < *data) ? &(*prv)->l : &(*prv)->r;
|
|
}
|
|
|
|
if (!*prv)
|
|
return 0;
|
|
|
|
BinaryNode *dl = *prv;
|
|
|
|
if (dl->r)
|
|
{
|
|
*prv = dl->r;
|
|
BinaryNode *left = dl->r;
|
|
|
|
while (left->l)
|
|
left = left->l;
|
|
|
|
left->l = dl->l;
|
|
|
|
} else
|
|
*prv = dl->l;
|
|
|
|
_RTC_Container* res = dl->val;
|
|
delete dl;
|
|
return res;
|
|
}
|
|
|
|
|
|
_RTC_Container *
|
|
_RTC_BinaryTree::FindNext(_RTC_BinaryTree::iter *i) throw()
|
|
{
|
|
// Return the next element from the iterator
|
|
// If the iterator is done, free up it's memory
|
|
if (++i->curSib >= i->totSibs)
|
|
{
|
|
VirtualFree(i->allSibs, 0, MEM_RELEASE);
|
|
i->curSib = i->totSibs = 0;
|
|
return 0;
|
|
} else
|
|
return i->allSibs[i->curSib];
|
|
}
|
|
|
|
_RTC_Container *
|
|
_RTC_BinaryTree::FindFirst(_RTC_BinaryTree::iter *i) throw()
|
|
{
|
|
// Initialize the iterator, and return it's first element
|
|
// Flatten the siblings into a nice array..
|
|
struct stk {
|
|
stk(stk *p, BinaryNode *i) : next(p), cur(i) {}
|
|
void *operator new(unsigned) {return _RTC_heap2->alloc();}
|
|
void operator delete(void *p) {_RTC_heap2->free(p);}
|
|
stk *next;
|
|
BinaryNode *cur;
|
|
};
|
|
|
|
stk *stack = new stk(0, this->tree);
|
|
stk *list = 0;
|
|
stk *tmp;
|
|
|
|
int count = 0;
|
|
|
|
// Build a list of all elements (reverse in-order traversal)
|
|
while (stack)
|
|
{
|
|
BinaryNode *cur = stack->cur;
|
|
tmp = stack;
|
|
stack = stack->next;
|
|
delete tmp;
|
|
while (cur)
|
|
{
|
|
list = new stk(list, cur);
|
|
count++;
|
|
if (cur->l)
|
|
stack = new stk(stack, cur->l);
|
|
cur = cur->r;
|
|
}
|
|
}
|
|
i->totSibs = 0;
|
|
i->curSib = 0;
|
|
if (!count)
|
|
{
|
|
i->allSibs = 0;
|
|
return 0;
|
|
}
|
|
|
|
i->allSibs = (_RTC_Container**)VirtualAlloc(0, sizeof(_RTC_Container*) * count,
|
|
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
|
|
while (list)
|
|
{
|
|
i->allSibs[i->totSibs++] = list->cur->val;
|
|
tmp = list;
|
|
list = list->next;
|
|
delete tmp;
|
|
}
|
|
return i->allSibs[0];
|
|
|
|
}
|
|
|
|
#endif // _RTC_ADVMEM
|
|
|