added b-tree templ

This commit is contained in:
Jeff Hill
1997-04-11 20:53:38 +00:00
parent f1865a507c
commit 2caf1628ca
7 changed files with 833 additions and 1 deletions
+1 -1
View File
@@ -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
+83
View File
@@ -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;
}
+80
View File
@@ -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;
}
+253
View File
@@ -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;
}
+253
View File
@@ -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;
};