added b-tree templ
This commit is contained in:
@@ -5,7 +5,7 @@ include $(TOP)/config/CONFIG_BASE
|
||||
CXXCMPLR = STRICT
|
||||
|
||||
TESTPROD := resourceLibTest tsDLListBench tsDLListTest tsDLListTest \
|
||||
tsSLListBench tsSLListTest minmaxTest
|
||||
tsSLListBench tsSLListTest minmaxTest tsBTreeBench tsBTreeTest
|
||||
|
||||
include $(TOP)/config/RULES.Host
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "tsBTree.h"
|
||||
#include "tsSLList.h"
|
||||
|
||||
class A : public tsBTreeNode<A>, public tsSLNode<A> {
|
||||
public:
|
||||
A()
|
||||
{
|
||||
key = (unsigned) rand();
|
||||
}
|
||||
|
||||
btCmp tsBTreeCompare(const A &item) const
|
||||
{
|
||||
if (this->key<=item.key) {
|
||||
return btLessOrEqual;
|
||||
}
|
||||
else {
|
||||
return btGreater;
|
||||
}
|
||||
}
|
||||
|
||||
void show()
|
||||
{
|
||||
printf("A: %u\n", key);
|
||||
}
|
||||
private:
|
||||
unsigned key;
|
||||
};
|
||||
|
||||
#define LOOPCOUNT 10000u
|
||||
|
||||
main ()
|
||||
{
|
||||
unsigned i;
|
||||
tsBTree<A> tree;
|
||||
tsSLList<A> list;
|
||||
A *pA;
|
||||
A a;
|
||||
clock_t clk;
|
||||
clock_t diff;
|
||||
double delay;
|
||||
|
||||
tree.insert(a);
|
||||
list.add(a);
|
||||
|
||||
for (i=0u; i<LOOPCOUNT; i++) {
|
||||
pA = new A;
|
||||
assert(pA);
|
||||
tree.insert(*pA);
|
||||
list.add(*pA);
|
||||
}
|
||||
|
||||
clk = clock();
|
||||
for (i=0u; i<LOOPCOUNT; i++) {
|
||||
assert(tree.verify(a));
|
||||
}
|
||||
diff = clock() - clk;
|
||||
delay = diff;
|
||||
delay = delay/CLOCKS_PER_SEC;
|
||||
delay = delay/LOOPCOUNT;
|
||||
printf("delay = %15.10f\n", delay);
|
||||
|
||||
clk = clock();
|
||||
while ( (pA = list.get()) ) {
|
||||
assert(tree.remove(*pA));
|
||||
}
|
||||
diff = clock() - clk;
|
||||
delay = diff;
|
||||
delay = delay/CLOCKS_PER_SEC;
|
||||
delay = delay/LOOPCOUNT;
|
||||
printf("delay = %15.10f\n", delay);
|
||||
|
||||
tree.traverse(A::show);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tsBTree.h"
|
||||
|
||||
class A : public tsBTreeNode<A> {
|
||||
public:
|
||||
A(const char *pNameIn) : pName(pNameIn) {}
|
||||
|
||||
btCmp tsBTreeCompare(const A &item) const
|
||||
{
|
||||
int cmp = strcmp(this->pName, item.pName);
|
||||
if (cmp<=0) {
|
||||
return btLessOrEqual;
|
||||
}
|
||||
else {
|
||||
return btGreater;
|
||||
}
|
||||
}
|
||||
|
||||
void show()
|
||||
{
|
||||
printf("A: %s\n", pName);
|
||||
}
|
||||
private:
|
||||
const char *pName;
|
||||
};
|
||||
|
||||
main ()
|
||||
{
|
||||
tsBTree<A> tree;
|
||||
A a0("fred");
|
||||
A a1("jane");
|
||||
A a2("jane0");
|
||||
A a3("bill");
|
||||
A a4("jane");
|
||||
A a5("dan");
|
||||
A a6("joe");
|
||||
|
||||
tree.insert(a0);
|
||||
tree.insert(a1);
|
||||
tree.insert(a2);
|
||||
tree.insert(a3);
|
||||
tree.insert(a4);
|
||||
tree.insert(a5);
|
||||
|
||||
tree.traverse(A::show);
|
||||
|
||||
assert(!tree.remove(a6));
|
||||
tree.insert(a6);
|
||||
assert(tree.remove(a6));
|
||||
assert(tree.remove(a5));
|
||||
assert(!tree.remove(a5));
|
||||
assert(!tree.verify(a5));
|
||||
assert(tree.verify(a4));
|
||||
assert(tree.remove(a0));
|
||||
assert(!tree.verify(a0));
|
||||
assert(!tree.remove(a0));
|
||||
tree.insert(a5);
|
||||
assert(tree.verify(a5));
|
||||
assert(tree.verify(a2));
|
||||
assert(tree.remove(a2));
|
||||
assert(!tree.verify(a2));
|
||||
assert(!tree.remove(a2));
|
||||
assert(tree.verify(a5));
|
||||
assert(tree.remove(a5));
|
||||
assert(!tree.remove(a5));
|
||||
assert(!tree.remove(a0));
|
||||
assert(tree.remove(a4));
|
||||
assert(tree.remove(a3));
|
||||
assert(!tree.remove(a4));
|
||||
assert(tree.remove(a1));
|
||||
|
||||
tree.traverse(A::show);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
//
|
||||
// tsBTreeRMRet
|
||||
//
|
||||
template <class T>
|
||||
class tsBTreeRMRet {
|
||||
public:
|
||||
tsBTreeRMRet (unsigned foundItIn, T *pNewSegIn) :
|
||||
foundIt(foundItIn), pNewSeg(pNewSegIn) {}
|
||||
|
||||
const unsigned foundIt;
|
||||
T * const pNewSeg;
|
||||
};
|
||||
|
||||
//
|
||||
// tsBTreeNode
|
||||
//
|
||||
template <class T>
|
||||
class tsBTreeNode
|
||||
{
|
||||
friend class tsBTree<T>;
|
||||
public:
|
||||
//
|
||||
// when someone copies into a class deriving from this
|
||||
// do _not_ change the node pointers
|
||||
//
|
||||
void operator = (tsBTreeNode<T> &) {}
|
||||
|
||||
enum btCmp {btGreater, btLessOrEqual};
|
||||
|
||||
//
|
||||
// class T must supply this member function which
|
||||
// comapres *this with item
|
||||
//
|
||||
// returns:
|
||||
// btGreater *this is greater than item
|
||||
// btLessOrEqual *this is less than or equal to item
|
||||
//
|
||||
// btCmp tsBTreeCompare(const T &item) const;
|
||||
//
|
||||
|
||||
private:
|
||||
T *pLeft;
|
||||
T *pRight;
|
||||
|
||||
static void traverse(T &self, void (T::*pCB)())
|
||||
{
|
||||
if (self.tsBTreeNode<T>::pLeft) {
|
||||
tsBTreeNode<T>::traverse
|
||||
(*self.tsBTreeNode<T>::pLeft, pCB);
|
||||
}
|
||||
(self.*pCB)();
|
||||
if (self.tsBTreeNode<T>::pRight) {
|
||||
tsBTreeNode<T>::traverse
|
||||
(*self.tsBTreeNode<T>::pRight, pCB);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE:
|
||||
// no change to item.pLeft and item.pRight here
|
||||
// so that an segment of a tree can be inserted
|
||||
//
|
||||
static void insert(T &self, T &item)
|
||||
{
|
||||
btCmp result = item.tsBTreeCompare(self);
|
||||
if (result==btLessOrEqual) {
|
||||
if (self.tsBTreeNode<T>::pLeft) {
|
||||
tsBTreeNode<T>::insert
|
||||
(*self.tsBTreeNode<T>::pLeft, item);
|
||||
}
|
||||
else {
|
||||
self.tsBTreeNode<T>::pLeft = &item;
|
||||
}
|
||||
}
|
||||
else if(result==btGreater) {
|
||||
if (self.tsBTreeNode<T>::pRight) {
|
||||
tsBTreeNode<T>::insert
|
||||
(*self.tsBTreeNode<T>::pRight, item);
|
||||
}
|
||||
else {
|
||||
self.tsBTreeNode<T>::pRight = &item;
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// remove()
|
||||
// returns pointer to modified tree and found/not found
|
||||
// (NULL if this portion of the tree is empty)
|
||||
//
|
||||
static tsBTreeRMRet<T> remove(T &self, T &item)
|
||||
{
|
||||
if (&self == &item) {
|
||||
if (self.tsBTreeNode<T>::pLeft) {
|
||||
if (self.tsBTreeNode<T>::pRight) {
|
||||
T *pR = self.tsBTreeNode<T>::pLeft->tsBTreeNode<T>::pRight;
|
||||
if (pR) {
|
||||
tsBTreeNode<T>::insert
|
||||
(*pR, *self.tsBTreeNode<T>::pRight);
|
||||
}
|
||||
else {
|
||||
self.tsBTreeNode<T>::pLeft->tsBTreeNode<T>::pRight =
|
||||
self.tsBTreeNode<T>::pRight;
|
||||
}
|
||||
}
|
||||
return tsBTreeRMRet<T>(1u, self.tsBTreeNode<T>::pLeft); // found it
|
||||
}
|
||||
else {
|
||||
return tsBTreeRMRet<T>(1u, self.tsBTreeNode<T>::pRight); // found it
|
||||
}
|
||||
}
|
||||
|
||||
btCmp result = item.tsBTreeCompare(self);
|
||||
if (result==btLessOrEqual) {
|
||||
if (self.tsBTreeNode<T>::pLeft) {
|
||||
tsBTreeRMRet<T> ret = tsBTreeNode<T>::
|
||||
remove(*self.tsBTreeNode<T>::pLeft, item);
|
||||
if (ret.foundIt) {
|
||||
self.tsBTreeNode<T>::pLeft= ret.pNewSeg;
|
||||
return tsBTreeRMRet<T>(1u,&self); // TRUE - found it
|
||||
}
|
||||
}
|
||||
return tsBTreeRMRet<T>(0u, 0u); // not found
|
||||
}
|
||||
else if(result==btGreater) {
|
||||
if (self.tsBTreeNode<T>::pRight) {
|
||||
tsBTreeRMRet<T> ret = tsBTreeNode<T>::
|
||||
remove(*self.tsBTreeNode<T>::pRight, item);
|
||||
if (ret.foundIt) {
|
||||
self.tsBTreeNode<T>::pRight = ret.pNewSeg;
|
||||
return tsBTreeRMRet<T>(1u,&self); // TRUE - found it
|
||||
}
|
||||
}
|
||||
return tsBTreeRMRet<T>(0u, 0u); // not found
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
//
|
||||
// verify
|
||||
//
|
||||
static unsigned verify(const T &self, const T &item)
|
||||
{
|
||||
if (&self == &item) {
|
||||
return 1u; // TRUE -item is present
|
||||
}
|
||||
btCmp result = item.tsBTreeCompare(self);
|
||||
if (result==btLessOrEqual) {
|
||||
if (self.tsBTreeNode<T>::pLeft) {
|
||||
return tsBTreeNode<T>::verify
|
||||
(*self.tsBTreeNode<T>::pLeft, item);
|
||||
}
|
||||
else {
|
||||
return 0u; // FALSE - not found
|
||||
}
|
||||
}
|
||||
else if(result==btGreater) {
|
||||
if (self.tsBTreeNode<T>::pRight) {
|
||||
return tsBTreeNode<T>::verify
|
||||
(*self.tsBTreeNode<T>::pRight, item);
|
||||
}
|
||||
else {
|
||||
return 0u; // FALSE - not found
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// tsBTree
|
||||
//
|
||||
template <class T>
|
||||
class tsBTree
|
||||
{
|
||||
public:
|
||||
tsBTree() : pRoot(0u) {}
|
||||
|
||||
// ~tsBTree()
|
||||
// {
|
||||
// this->traverse(T::~T);
|
||||
// }
|
||||
|
||||
void insert(T &item)
|
||||
{
|
||||
item.tsBTreeNode<T>::pLeft = 0;
|
||||
item.tsBTreeNode<T>::pRight = 0;
|
||||
if (this->pRoot) {
|
||||
tsBTreeNode<T>::insert(*this->pRoot, item);
|
||||
}
|
||||
else {
|
||||
this->pRoot = &item;
|
||||
}
|
||||
}
|
||||
//
|
||||
// remove item from the tree
|
||||
//
|
||||
// returns true if item was in the tree
|
||||
// (otherwise FALSE)
|
||||
//
|
||||
unsigned remove(T &item)
|
||||
{
|
||||
if (this->pRoot) {
|
||||
tsBTreeRMRet<T> ret =
|
||||
tsBTreeNode<T>::remove(*this->pRoot, item);
|
||||
if (ret.foundIt) {
|
||||
this->pRoot = ret.pNewSeg;
|
||||
return 1u; // TRUE - found it
|
||||
}
|
||||
}
|
||||
return 0u; // FALSE - not found
|
||||
}
|
||||
//
|
||||
// verify that item is in the tree
|
||||
//
|
||||
// returns true if item is in the tree
|
||||
// (otherwise FALSE)
|
||||
//
|
||||
unsigned verify(T &item) const
|
||||
{
|
||||
if (this->pRoot) {
|
||||
return tsBTreeNode<T>::verify(*this->pRoot, item);
|
||||
}
|
||||
else {
|
||||
return 0u; // FALSE - not found
|
||||
}
|
||||
}
|
||||
//
|
||||
// Call (pT->*pCB) () for each item in the table
|
||||
//
|
||||
// where pT is a pointer to type T and pCB is
|
||||
// a pointer to a memmber function of T with
|
||||
// no parameters and returning void
|
||||
//
|
||||
void traverse(void (T::*pCB)())
|
||||
{
|
||||
if (this->pRoot) {
|
||||
tsBTreeNode<T>::traverse(*this->pRoot, pCB);
|
||||
}
|
||||
}
|
||||
private:
|
||||
T *pRoot;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "tsBTree.h"
|
||||
#include "tsSLList.h"
|
||||
|
||||
class A : public tsBTreeNode<A>, public tsSLNode<A> {
|
||||
public:
|
||||
A()
|
||||
{
|
||||
key = (unsigned) rand();
|
||||
}
|
||||
|
||||
btCmp tsBTreeCompare(const A &item) const
|
||||
{
|
||||
if (this->key<=item.key) {
|
||||
return btLessOrEqual;
|
||||
}
|
||||
else {
|
||||
return btGreater;
|
||||
}
|
||||
}
|
||||
|
||||
void show()
|
||||
{
|
||||
printf("A: %u\n", key);
|
||||
}
|
||||
private:
|
||||
unsigned key;
|
||||
};
|
||||
|
||||
#define LOOPCOUNT 10000u
|
||||
|
||||
main ()
|
||||
{
|
||||
unsigned i;
|
||||
tsBTree<A> tree;
|
||||
tsSLList<A> list;
|
||||
A *pA;
|
||||
A a;
|
||||
clock_t clk;
|
||||
clock_t diff;
|
||||
double delay;
|
||||
|
||||
tree.insert(a);
|
||||
list.add(a);
|
||||
|
||||
for (i=0u; i<LOOPCOUNT; i++) {
|
||||
pA = new A;
|
||||
assert(pA);
|
||||
tree.insert(*pA);
|
||||
list.add(*pA);
|
||||
}
|
||||
|
||||
clk = clock();
|
||||
for (i=0u; i<LOOPCOUNT; i++) {
|
||||
assert(tree.verify(a));
|
||||
}
|
||||
diff = clock() - clk;
|
||||
delay = diff;
|
||||
delay = delay/CLOCKS_PER_SEC;
|
||||
delay = delay/LOOPCOUNT;
|
||||
printf("delay = %15.10f\n", delay);
|
||||
|
||||
clk = clock();
|
||||
while ( (pA = list.get()) ) {
|
||||
assert(tree.remove(*pA));
|
||||
}
|
||||
diff = clock() - clk;
|
||||
delay = diff;
|
||||
delay = delay/CLOCKS_PER_SEC;
|
||||
delay = delay/LOOPCOUNT;
|
||||
printf("delay = %15.10f\n", delay);
|
||||
|
||||
tree.traverse(A::show);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tsBTree.h"
|
||||
|
||||
class A : public tsBTreeNode<A> {
|
||||
public:
|
||||
A(const char *pNameIn) : pName(pNameIn) {}
|
||||
|
||||
btCmp tsBTreeCompare(const A &item) const
|
||||
{
|
||||
int cmp = strcmp(this->pName, item.pName);
|
||||
if (cmp<=0) {
|
||||
return btLessOrEqual;
|
||||
}
|
||||
else {
|
||||
return btGreater;
|
||||
}
|
||||
}
|
||||
|
||||
void show()
|
||||
{
|
||||
printf("A: %s\n", pName);
|
||||
}
|
||||
private:
|
||||
const char *pName;
|
||||
};
|
||||
|
||||
main ()
|
||||
{
|
||||
tsBTree<A> tree;
|
||||
A a0("fred");
|
||||
A a1("jane");
|
||||
A a2("jane0");
|
||||
A a3("bill");
|
||||
A a4("jane");
|
||||
A a5("dan");
|
||||
A a6("joe");
|
||||
|
||||
tree.insert(a0);
|
||||
tree.insert(a1);
|
||||
tree.insert(a2);
|
||||
tree.insert(a3);
|
||||
tree.insert(a4);
|
||||
tree.insert(a5);
|
||||
|
||||
tree.traverse(A::show);
|
||||
|
||||
assert(!tree.remove(a6));
|
||||
tree.insert(a6);
|
||||
assert(tree.remove(a6));
|
||||
assert(tree.remove(a5));
|
||||
assert(!tree.remove(a5));
|
||||
assert(!tree.verify(a5));
|
||||
assert(tree.verify(a4));
|
||||
assert(tree.remove(a0));
|
||||
assert(!tree.verify(a0));
|
||||
assert(!tree.remove(a0));
|
||||
tree.insert(a5);
|
||||
assert(tree.verify(a5));
|
||||
assert(tree.verify(a2));
|
||||
assert(tree.remove(a2));
|
||||
assert(!tree.verify(a2));
|
||||
assert(!tree.remove(a2));
|
||||
assert(tree.verify(a5));
|
||||
assert(tree.remove(a5));
|
||||
assert(!tree.remove(a5));
|
||||
assert(!tree.remove(a0));
|
||||
assert(tree.remove(a4));
|
||||
assert(tree.remove(a3));
|
||||
assert(!tree.remove(a4));
|
||||
assert(tree.remove(a1));
|
||||
|
||||
tree.traverse(A::show);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
//
|
||||
// tsBTreeRMRet
|
||||
//
|
||||
template <class T>
|
||||
class tsBTreeRMRet {
|
||||
public:
|
||||
tsBTreeRMRet (unsigned foundItIn, T *pNewSegIn) :
|
||||
foundIt(foundItIn), pNewSeg(pNewSegIn) {}
|
||||
|
||||
const unsigned foundIt;
|
||||
T * const pNewSeg;
|
||||
};
|
||||
|
||||
//
|
||||
// tsBTreeNode
|
||||
//
|
||||
template <class T>
|
||||
class tsBTreeNode
|
||||
{
|
||||
friend class tsBTree<T>;
|
||||
public:
|
||||
//
|
||||
// when someone copies into a class deriving from this
|
||||
// do _not_ change the node pointers
|
||||
//
|
||||
void operator = (tsBTreeNode<T> &) {}
|
||||
|
||||
enum btCmp {btGreater, btLessOrEqual};
|
||||
|
||||
//
|
||||
// class T must supply this member function which
|
||||
// comapres *this with item
|
||||
//
|
||||
// returns:
|
||||
// btGreater *this is greater than item
|
||||
// btLessOrEqual *this is less than or equal to item
|
||||
//
|
||||
// btCmp tsBTreeCompare(const T &item) const;
|
||||
//
|
||||
|
||||
private:
|
||||
T *pLeft;
|
||||
T *pRight;
|
||||
|
||||
static void traverse(T &self, void (T::*pCB)())
|
||||
{
|
||||
if (self.tsBTreeNode<T>::pLeft) {
|
||||
tsBTreeNode<T>::traverse
|
||||
(*self.tsBTreeNode<T>::pLeft, pCB);
|
||||
}
|
||||
(self.*pCB)();
|
||||
if (self.tsBTreeNode<T>::pRight) {
|
||||
tsBTreeNode<T>::traverse
|
||||
(*self.tsBTreeNode<T>::pRight, pCB);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE:
|
||||
// no change to item.pLeft and item.pRight here
|
||||
// so that an segment of a tree can be inserted
|
||||
//
|
||||
static void insert(T &self, T &item)
|
||||
{
|
||||
btCmp result = item.tsBTreeCompare(self);
|
||||
if (result==btLessOrEqual) {
|
||||
if (self.tsBTreeNode<T>::pLeft) {
|
||||
tsBTreeNode<T>::insert
|
||||
(*self.tsBTreeNode<T>::pLeft, item);
|
||||
}
|
||||
else {
|
||||
self.tsBTreeNode<T>::pLeft = &item;
|
||||
}
|
||||
}
|
||||
else if(result==btGreater) {
|
||||
if (self.tsBTreeNode<T>::pRight) {
|
||||
tsBTreeNode<T>::insert
|
||||
(*self.tsBTreeNode<T>::pRight, item);
|
||||
}
|
||||
else {
|
||||
self.tsBTreeNode<T>::pRight = &item;
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// remove()
|
||||
// returns pointer to modified tree and found/not found
|
||||
// (NULL if this portion of the tree is empty)
|
||||
//
|
||||
static tsBTreeRMRet<T> remove(T &self, T &item)
|
||||
{
|
||||
if (&self == &item) {
|
||||
if (self.tsBTreeNode<T>::pLeft) {
|
||||
if (self.tsBTreeNode<T>::pRight) {
|
||||
T *pR = self.tsBTreeNode<T>::pLeft->tsBTreeNode<T>::pRight;
|
||||
if (pR) {
|
||||
tsBTreeNode<T>::insert
|
||||
(*pR, *self.tsBTreeNode<T>::pRight);
|
||||
}
|
||||
else {
|
||||
self.tsBTreeNode<T>::pLeft->tsBTreeNode<T>::pRight =
|
||||
self.tsBTreeNode<T>::pRight;
|
||||
}
|
||||
}
|
||||
return tsBTreeRMRet<T>(1u, self.tsBTreeNode<T>::pLeft); // found it
|
||||
}
|
||||
else {
|
||||
return tsBTreeRMRet<T>(1u, self.tsBTreeNode<T>::pRight); // found it
|
||||
}
|
||||
}
|
||||
|
||||
btCmp result = item.tsBTreeCompare(self);
|
||||
if (result==btLessOrEqual) {
|
||||
if (self.tsBTreeNode<T>::pLeft) {
|
||||
tsBTreeRMRet<T> ret = tsBTreeNode<T>::
|
||||
remove(*self.tsBTreeNode<T>::pLeft, item);
|
||||
if (ret.foundIt) {
|
||||
self.tsBTreeNode<T>::pLeft= ret.pNewSeg;
|
||||
return tsBTreeRMRet<T>(1u,&self); // TRUE - found it
|
||||
}
|
||||
}
|
||||
return tsBTreeRMRet<T>(0u, 0u); // not found
|
||||
}
|
||||
else if(result==btGreater) {
|
||||
if (self.tsBTreeNode<T>::pRight) {
|
||||
tsBTreeRMRet<T> ret = tsBTreeNode<T>::
|
||||
remove(*self.tsBTreeNode<T>::pRight, item);
|
||||
if (ret.foundIt) {
|
||||
self.tsBTreeNode<T>::pRight = ret.pNewSeg;
|
||||
return tsBTreeRMRet<T>(1u,&self); // TRUE - found it
|
||||
}
|
||||
}
|
||||
return tsBTreeRMRet<T>(0u, 0u); // not found
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
//
|
||||
// verify
|
||||
//
|
||||
static unsigned verify(const T &self, const T &item)
|
||||
{
|
||||
if (&self == &item) {
|
||||
return 1u; // TRUE -item is present
|
||||
}
|
||||
btCmp result = item.tsBTreeCompare(self);
|
||||
if (result==btLessOrEqual) {
|
||||
if (self.tsBTreeNode<T>::pLeft) {
|
||||
return tsBTreeNode<T>::verify
|
||||
(*self.tsBTreeNode<T>::pLeft, item);
|
||||
}
|
||||
else {
|
||||
return 0u; // FALSE - not found
|
||||
}
|
||||
}
|
||||
else if(result==btGreater) {
|
||||
if (self.tsBTreeNode<T>::pRight) {
|
||||
return tsBTreeNode<T>::verify
|
||||
(*self.tsBTreeNode<T>::pRight, item);
|
||||
}
|
||||
else {
|
||||
return 0u; // FALSE - not found
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// tsBTree
|
||||
//
|
||||
template <class T>
|
||||
class tsBTree
|
||||
{
|
||||
public:
|
||||
tsBTree() : pRoot(0u) {}
|
||||
|
||||
// ~tsBTree()
|
||||
// {
|
||||
// this->traverse(T::~T);
|
||||
// }
|
||||
|
||||
void insert(T &item)
|
||||
{
|
||||
item.tsBTreeNode<T>::pLeft = 0;
|
||||
item.tsBTreeNode<T>::pRight = 0;
|
||||
if (this->pRoot) {
|
||||
tsBTreeNode<T>::insert(*this->pRoot, item);
|
||||
}
|
||||
else {
|
||||
this->pRoot = &item;
|
||||
}
|
||||
}
|
||||
//
|
||||
// remove item from the tree
|
||||
//
|
||||
// returns true if item was in the tree
|
||||
// (otherwise FALSE)
|
||||
//
|
||||
unsigned remove(T &item)
|
||||
{
|
||||
if (this->pRoot) {
|
||||
tsBTreeRMRet<T> ret =
|
||||
tsBTreeNode<T>::remove(*this->pRoot, item);
|
||||
if (ret.foundIt) {
|
||||
this->pRoot = ret.pNewSeg;
|
||||
return 1u; // TRUE - found it
|
||||
}
|
||||
}
|
||||
return 0u; // FALSE - not found
|
||||
}
|
||||
//
|
||||
// verify that item is in the tree
|
||||
//
|
||||
// returns true if item is in the tree
|
||||
// (otherwise FALSE)
|
||||
//
|
||||
unsigned verify(T &item) const
|
||||
{
|
||||
if (this->pRoot) {
|
||||
return tsBTreeNode<T>::verify(*this->pRoot, item);
|
||||
}
|
||||
else {
|
||||
return 0u; // FALSE - not found
|
||||
}
|
||||
}
|
||||
//
|
||||
// Call (pT->*pCB) () for each item in the table
|
||||
//
|
||||
// where pT is a pointer to type T and pCB is
|
||||
// a pointer to a memmber function of T with
|
||||
// no parameters and returning void
|
||||
//
|
||||
void traverse(void (T::*pCB)())
|
||||
{
|
||||
if (this->pRoot) {
|
||||
tsBTreeNode<T>::traverse(*this->pRoot, pCB);
|
||||
}
|
||||
}
|
||||
private:
|
||||
T *pRoot;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user