This commit is contained in:
peterl%netscape.com 1999-07-24 18:57:59 +00:00
parent 6f23083749
commit 23918a8d61
4 changed files with 0 additions and 1331 deletions

View File

@ -1,402 +0,0 @@
/**
* This file defines the binary tree class and it
* nsNode child class.
*
* This simple version stores nodes, and the
* nodes store void* ptrs.
*
* @update gess 4/11/98
* @param
* @return
*/
#include "nsBTree.h"
/**
* default constructor
*
* @update gess 4/11/98
*/
nsNode::nsNode(){
mLeft=0;
mRight=0;
mParent=0;
mColor=eBlack;
}
/**
* Copy constructor
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode::nsNode(const nsNode& aNode){
mLeft=aNode.mLeft;
mRight=aNode.mRight;
mParent=aNode.mParent;
mColor=aNode.mColor;
}
/**
* destructor
*
* @update gess 4/11/98
*/
nsNode::~nsNode(){
}
/**
* Retrive ptr to parent node
*
* @update gess 4/11/98
* @return ptr to parent node
*/
nsNode* nsNode::GetParentNode(void) const{
return mParent;
}
/**
* Retrieve ptr to left (less) node
*
* @update gess 4/11/98
* @return ptr to left (may be NULL)
*/
nsNode* nsNode::GetLeftNode(void) const{
return mLeft;
}
/**
* Retrieve ptr to right (more) node
*
* @update gess 4/11/98
* @return ptr to right node (may be NULL)
*/
nsNode* nsNode::GetRightNode(void) const{
return mRight;
}
/**
*
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode& nsNode::operator=(const nsNode& aNode){
if(this!=&aNode){
mLeft=aNode.mLeft;
mRight=aNode.mRight;
mParent=aNode.mParent;
mColor=aNode.mColor;
}
return *this;
}
/********************************************************
* Here comes the BTREE class...
********************************************************/
/**
* nsBTree constructor
*
* @update gess 4/11/98
*/
nsBTree::nsBTree(){
mRoot=0;
}
/**
* destructor
*
* @update gess 4/11/98
*/
nsBTree::~nsBTree(){
if(mRoot){
//walk the tree and destroy the children.
}
}
/**
* Given a node, we're supposed to add it into
* our tree.
*
* @update gess 4/11/98
* @param aNode to be added to tree
* @return ptr to added node or NULL
*/
nsNode* nsBTree::Add(nsNode& aNode){
nsNode* node1=mRoot; //x
nsNode* node2=0; //y
while(node1) {
node2=node1;
if(aNode<*node1)
node1=node1->mLeft;
else node1=node1->mRight;
}
aNode.mParent=node2;
if(!node2){
mRoot=&aNode;
}
else{
if(aNode<*node2)
node2->mLeft=&aNode;
else node2->mRight=&aNode;
}
return &aNode;
}
/**
* Removes given node from tree if present.
*
* @update gess 4/11/98
* @param aNode to be found and removed
* @return ptr to remove node, or NULL
*/
nsNode* nsBTree::Remove(nsNode& aNode){
nsNode* result=0;
nsNode* node3=Find(aNode);
if(node3) {
nsNode* node1;
nsNode* node2;
if((!node3->mLeft) || (!node3->mRight))
node2=node3;
else node2=After(*node3);
if(node2->mLeft)
node1=node2->mLeft;
else node1=node2->mRight;
if(node1)
node1->mParent=node2->mParent;
if(node2->mParent) {
if(node2==node2->mParent->mLeft)
node2->mParent->mLeft=node1;
else node2->mParent->mRight=node1;
}
else mRoot=node1;
if(node2!=node3)
(*node3)==(*node2);
if(node2->mColor == nsNode::eBlack)
ReBalance(*node1);
delete node2;
result=&aNode;
}
return result;
}
/**
* Clears the tree of any data.
* Be careful here if your objects are heap based!
* This method doesn't free the objects, so if you
* don't have your own pointers, they will become
* orphaned.
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& nsBTree::Empty(nsNode* aNode) {
mRoot=0;
return *this;
}
/**
* This method destroys all the objects in the tree.
* WARNING: Never call this method on stored objects
* that are stack-based!
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& nsBTree::Erase(nsNode* aNode){
// nsNode* node1 =(aNode) ? aNode : mRoot;
if(aNode) {
Erase(aNode->mLeft); //begin by walking left side
Erase(aNode->mRight); //then search right side
delete aNode; //until a leaf, then delete
}
return *this;
}
/**
* Retrieve ptr to first node in tree
*
* @update gess 4/11/98
* @return
*/
nsNode* nsBTree::First(void) const{
if(mRoot)
return First(*mRoot);
return 0;
}
/**
* Retrive ptr to first node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to first node from given node or NULL
*/
nsNode* nsBTree::First(const nsNode& aNode) const{
nsNode* result=0;
if(mRoot) {
result=mRoot;
while(result->GetLeftNode()) {
result=result->GetLeftNode();
}
}
return result;
}
/**
* Retrive ptr to last node
*
* @update gess 4/11/98
* @return ptr to last node rel to root or NULL
*/
nsNode* nsBTree::Last(void) const{
if(mRoot)
return Last(*mRoot);
return 0;
}
/**
* Retrive ptr to last node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to first node from given node or NULL
*/
nsNode* nsBTree::Last(const nsNode& aNode) const{
nsNode* result=0;
if(mRoot) {
result=mRoot;
while(result->GetRightNode()) {
result=result->GetRightNode();
}
}
return result;
}
/**
* Retrive ptr to prior node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to prior node from given node or NULL
*/
nsNode* nsBTree::Before(const nsNode& aNode) const{
if(aNode.GetLeftNode())
return Last(*aNode.GetLeftNode());
//otherwise...
nsNode* node1=(nsNode*)&aNode;
nsNode* node2=aNode.GetParentNode();
while((node2) && (node1==node2->GetLeftNode())) {
node1=node2;
node2=node2->GetParentNode();
}
return node2;
}
/**
* Retrive ptr to next node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to next node from given node or NULL
*/
nsNode* nsBTree::After(const nsNode& aNode) const{
if(aNode.GetRightNode())
return First(*aNode.GetRightNode());
//otherwise...
nsNode* node1=(nsNode*)&aNode;
nsNode* node2=aNode.GetParentNode();
while((node2) && (node1==node2->GetRightNode())) {
node1=node2;
node2=node2->GetParentNode();
}
return node2;
}
/**
* Scan for given node
*
* @update gess 4/11/98
* @param node to find
* @return ptr to given node, or NULL
*/
nsNode* nsBTree::Find(const nsNode& aNode) const{
nsNode* result=mRoot;
while((result) && (!(aNode==(*result)))) {
if(aNode<*result)
result=result->mLeft;
else result=result->mRight;
}
return (nsNode*)result;
}
/**
* Rebalances tree around the given node. This only
* needs to be called after a node is deleted.
* This method does nothing for btrees, but is
* needed for RBTrees.
*
* @update gess 4/11/98
* @param aNode -- node to balance around
* @return this
*/
nsBTree& nsBTree::ReBalance(nsNode& aNode){
return *this;
}
/**
*
*
* @update gess 4/11/98
* @param
* @return
*/
const nsBTree& nsBTree::ForEach(nsNodeFunctor& aFunctor,nsNode* aNode) const{
nsNode* node1 =(aNode) ? aNode : mRoot;
if(node1) {
if(node1->mLeft)
ForEach(aFunctor,node1->mLeft); //begin by walking left side
aFunctor(*node1);
if(node1->mRight)
ForEach(aFunctor,node1->mRight); //then search right side
}
return *this;
}

View File

@ -1,283 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* This file defines the binary tree class and it
* nsNode child class. Note that like all nsBTree
* containers, this one does not automatically balance.
* (Find for random data, bad for pre-ordered data).
*
* This simple version stores nodes, and the
* nodes store void* ptrs.
*
* @update gess 4/11/98
*/
/**
* nsNode
*
* @update gess 4/11/98
* @param
* @return
*/
#ifndef _BTREE_H
#define _BTREE_H
#include "nscore.h"
struct NS_COM nsNode {
/**
*
* @update gess4/20/98
* @param
* @return
*/
nsNode();
/**
* Copy constructor
* @update gess 4/11/98
*/
nsNode(const nsNode& aNode);
/**
* destructor
* @update gess 4/11/98
*/
virtual ~nsNode();
/**
* Retrieve parent node
*
* @update gess 4/11/98
* @return
*/
nsNode* GetParentNode(void) const;
/**
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* GetLeftNode() const;
/**
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* GetRightNode() const;
/**
*
* @update gess 4/11/98
* @param
* @return
*/
virtual nsNode& operator=(const nsNode& aNode);
/**
* This method gets called to determine which of
* two nodes is less. When you create your own
* subclass of nsNode, this is the most important
* method for you to overload.
*
* @update gess 4/11/98
* @param
* @return
*/
virtual PRBool operator<(const nsNode& aNode) const=0;
/**
* This method gets called to determine which of
* two nodes is less. When you create your own
* subclass of nsNode, this is the most important
* method for you to overload.
*
* @update gess 4/11/98
* @param
* @return
*/
virtual PRBool operator==(const nsNode& aNode) const=0;
enum eRBColor {eRed,eBlack};
nsNode* mParent;
nsNode* mLeft;
nsNode* mRight;
eRBColor mColor;
};
/**
* The Nodefunctor class is used when you want to create
* callbacks between the nsRBTree and your generic code.
*
* @update gess4/20/98
*/
class NS_COM nsNodeFunctor {
public:
virtual nsNodeFunctor& operator()(nsNode& aNode)=0;
};
/****************************************************
* Here comes the nsBTree class...
****************************************************/
class NS_COM nsBTree {
public:
friend class nsBTreeIterator;
nsBTree();
virtual ~nsBTree();
/**
* Add given node reference into our tree.
*
* @update gess 4/11/98
* @param aNode is a ref to a node to be added
* @return newly added node
*/
nsNode* Add(nsNode& aNode);
/**
* Remove given node reference into our tree.
*
* @update gess 4/11/98
* @param aNode is a ref to a node to be removed
* @return Ptr to node if found (and removed) or NULL
*/
nsNode* Remove(nsNode& aNode);
/**
* Clears the tree of any data.
* Be careful here if your objects are heap based!
* This method doesn't free the objects, so if you
* don't have your own pointers, they will become
* orphaned.
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& Empty(nsNode* aNode=0);
/**
* This method destroys all the objects in the tree.
* WARNING: Never call this method on stored objects
* that are stack-based!
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& Erase(nsNode* aNode=0);
/**
* Retrieve ptr to 1st node in tree (starting at root)
*
* @update gess 4/11/98
* @return ptr to 1st node, possible to be NULL
*/
nsNode* First(void) const;
/**
* Find first node in tree starting at given node
*
* @update gess 4/11/98
* @param aNode node to begin 1st search from
* @return ptr to 1st node below given node
*/
nsNode* First(const nsNode& aNode) const;
/**
* Retrieve ptr to last node in tree relative to root.
*
* @update gess 4/11/98
* @return ptr to last node or NULL
*/
nsNode* Last(void) const;
/**
* Retrieve ptr to last node in tree relative to given node.
*
* @update gess 4/11/98
* @param node to find last node from
* @return ptr to last node or NULL
*/
nsNode* Last(const nsNode& aNode) const;
/**
* Retrieve a ptr to the node that preceeds given node
*
* @update gess 4/11/98
* @param aNode used as reference to find prev.
* @return ptr to prev node or NULL
*/
nsNode* Before(const nsNode& aNode) const;
/**
* Retrieve a ptr to the node after given node
*
* @update gess 4/11/98
* @param aNode used as reference to find next.
* @return ptr to next node or NULL
*/
nsNode* After(const nsNode& aNode) const;
/**
* Find given node in tree.
* (Why would you want to find a node you already have?)
*
* @update gess 4/11/98
* @param aNode is the node you're searching for
* @return ptr to node if found, or NULL
*/
nsNode* Find(const nsNode& aNode) const;
/**
* Walks the tree, starting with root.
*
* @update gess 4/11/98
*/
virtual const nsBTree& ForEach(nsNodeFunctor& aFunctor,nsNode* aNode=0) const;
protected:
/**
* Rebalances tree around the given node. This only
* needs to be called after a node is deleted.
*
* @update gess 4/11/98
* @param aNode -- node to balance around
* @return this
*/
virtual nsBTree& ReBalance(nsNode& aNode);
nsNode* mRoot;
};
#endif

View File

@ -1,423 +0,0 @@
/**
* This file defines the binary tree class and it
* nsNode child class.
*
* This simple version stores nodes, and the
* nodes store void* ptrs.
*
* @update gess 4/11/98
* @param
* @return
*/
#include "nsRBTree.h"
/**************************************************
Here comes the nsRBTree class...
*************************************************/
/**
* nsRBTree constructor
*
* @update gess 4/11/98
*/
nsRBTree::nsRBTree() : nsBTree() {
mRoot=0;
}
/**
* nsRBTree constructor
*
* @update gess 4/11/98
*/
nsRBTree::nsRBTree(const nsRBTree& aCopy) : nsBTree(aCopy) {
mRoot=aCopy.mRoot;
}
/**
* nsRBTree destructor
*
* @update gess 4/11/98
* @param
* @return
*/
nsRBTree::~nsRBTree(){
if(mRoot){
//walk the tree and destroy the children.
}
}
/**
* Given a node, we're supposed to add it into
* our tree.
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* nsRBTree::Add(nsNode& aNode){
nsBTree::Add(aNode);
nsNode* node1=&aNode;
nsNode* node2=0;
node1->mColor=nsNode::eRed;
while((node1!=mRoot) && (node1->mParent->mColor==nsNode::eRed)) {
if(node1->mParent==node1->mParent->mParent->mLeft) {
node2=node1->mParent->mParent->mLeft;
if(node2->mColor==nsNode::eRed) {
node1->mParent->mColor=nsNode::eBlack;
node2->mColor=nsNode::eBlack;
node1->mParent->mParent->mColor=nsNode::eRed;
node1=node1->mParent->mParent;
}
else {
if(node1==node1->mParent->mRight) {
node1=node1->mParent;
ShiftLeft(*node1);
}
node1->mParent->mColor=nsNode::eBlack;
node1->mParent->mParent->mColor=nsNode::eRed;
ShiftRight(*node1->mParent->mParent);
}
}
else {
node2=node1->mParent->mParent->mRight;
if (node2->mColor==nsNode::eRed){
node1->mParent->mColor=nsNode::eBlack;
node2->mColor=nsNode::eBlack;
node1->mParent->mParent->mColor=nsNode::eRed;
node1=node1->mParent->mParent;
}
else {
if (node1==node1->mParent->mLeft) {
node1=node1->mParent;
ShiftRight(*node1);
}
node1->mParent->mColor=nsNode::eBlack;
node1->mParent->mParent->mColor=nsNode::eRed;
ShiftLeft(*node1->mParent->mParent);
}
}
}
mRoot->mColor=nsNode::eBlack;
return &aNode;
}
/**
* Retrive the first node in the tree
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* nsRBTree::First(){
nsNode* result=First(*mRoot);
return result;
}
/**
* Retrieve the first node given a starting node
*
* @update gess 4/11/98
* @param aNode --
* @return node ptr or null
*/
nsNode* nsRBTree::First(nsNode& aNode){
nsNode* result=0;
if(mRoot) {
result=mRoot;
while(result->GetLeftNode()) {
result=result->GetLeftNode();
}
}
return result;
}
/**
* Find the last node in the tree
*
* @update gess 4/11/98
* @param
* @return node ptr or null
*/
nsNode* nsRBTree::Last(){
nsNode* result=Last(*mRoot);
return result;
}
/**
* Find the last node from a given node
*
* @update gess 4/11/98
* @param aNode -- node ptr to start from
* @return node ptr or null
*/
nsNode* nsRBTree::Last(nsNode& aNode){
nsNode* result=0;
if(mRoot) {
result=mRoot;
while(result->GetRightNode()) {
result=result->GetRightNode();
}
}
return result;
}
/**
* Retrieve the node that preceeds the given node
*
* @update gess 4/11/98
* @param aNode -- node to find precedent of
* @return preceeding node ptr, or null
*/
nsNode* nsRBTree::Before(nsNode& aNode){
if(aNode.GetLeftNode())
return Last(*aNode.GetLeftNode());
//otherwise...
nsNode* node1=&aNode;
nsNode* node2=aNode.GetParentNode();
while((node2) && (node1==node2->GetLeftNode())) {
node1=node2;
node2=node2->GetParentNode();
}
return node2;
}
/**
* Retrieve a ptr to the node following the given node
*
* @update gess 4/11/98
* @param aNode -- node to find successor node from
* @return node ptr or null
*/
nsNode* nsRBTree::After(nsNode& aNode){
if(aNode.GetRightNode())
return First(*aNode.GetRightNode());
//otherwise...
nsNode* node1=&aNode;
nsNode* node2=aNode.GetParentNode();
while((node2) && (node1==node2->GetRightNode())) {
node1=node2;
node2=node2->GetParentNode();
}
return node2;
}
/**
* Find a (given) node in the tree
*
* @update gess 4/11/98
* @param node to find in the tree
* @return node ptr (if found) or null
*/
nsNode* nsRBTree::Find(nsNode& aNode){
nsNode* result=mRoot;
while((result) && (!((*result)==aNode))) {
if(aNode<*result)
result=result->mLeft;
else result=result->mRight;
}
return result;
}
/**
* Causes a shift to the left, to keep the
* underlying RB data in balance
*
* @update gess 4/11/98
* @param
* @return this
*/
nsRBTree& nsRBTree::ShiftLeft(nsNode& aNode){
nsNode* temp= aNode.mRight;
aNode.mRight=temp->mLeft;
if(temp->mLeft)
temp->mRight->mParent=&aNode;
temp->mParent= aNode.mParent;
if (aNode.mParent) {
if (&aNode==aNode.mParent->mLeft)
aNode.mParent->mLeft=temp;
else aNode.mParent->mRight=temp;
}
else mRoot=temp;
temp->mLeft=&aNode;;
aNode.mParent=temp;
return *this;
}
/**
* Causes a shift right to occur, to keep the
* underlying RB data in balance
*
* @update gess 4/11/98
* @param aNode -- node at which to perform shift
* @return this
*/
nsRBTree& nsRBTree::ShiftRight(nsNode& aNode){
nsNode* temp=aNode.mLeft;
aNode.mLeft=temp->mRight;
if(temp->mRight)
temp->mRight->mParent=&aNode;
temp->mParent=aNode.mParent;
if(aNode.mParent){
if(&aNode==aNode.mParent->mRight)
aNode.mParent->mRight=temp;
else aNode.mParent->mLeft=temp;
}
else mRoot=temp;
temp->mRight=&aNode;
aNode.mParent=temp;
return *this;
}
/**
* Rebalances tree around the given node. This only
* needs to be called after a node is deleted.
*
* @update gess 4/11/98
* @param aNode -- node to balance around
* @return this
*/
nsBTree& nsRBTree::ReBalance(nsNode& aNode){
nsNode* node1=&aNode;
nsNode* node2=0;
while ((node1!=mRoot) && (node1->mColor==nsNode::eBlack)) {
if(node1==node1->mParent->mLeft) {
node2=node1->mParent->mRight;
if(node2->mColor==nsNode::eRed) {
node2->mColor=nsNode::eBlack;
node1->mParent->mColor=nsNode::eRed;
ShiftLeft(*node1->mParent);
node2=node1->mParent->mRight;
}
if((node2->mLeft->mColor == nsNode::eBlack) &&
(node2->mRight->mColor == nsNode::eBlack)) {
node2->mColor=nsNode::eRed;
node1=node1->mParent;
}
else {
if(node2->mRight->mColor == nsNode::eBlack) {
node2->mLeft->mColor=nsNode::eBlack;
node2->mColor=nsNode::eRed;
ShiftRight(*node2);
node2=node1->mParent->mRight;
}
node2->mColor=node1->mParent->mColor;
node1->mParent->mColor=nsNode::eBlack;
node2->mRight->mColor=nsNode::eBlack;
ShiftLeft(*node1->mParent);
node1=mRoot;
} //else
}
else {
node2=node1->mParent->mLeft;
if(node2->mColor==nsNode::eRed) {
node2->mColor=nsNode::eBlack;
node1->mParent->mColor=nsNode::eRed;
ShiftRight(*node1->mParent);
node2=node1->mParent->mLeft;
}
if((node2->mRight->mColor == nsNode::eBlack) &&
(node2->mLeft->mColor == nsNode::eBlack)) {
node2->mColor=nsNode::eRed;
node1=node1->mParent;
}
else {
if(node2->mLeft->mColor == nsNode::eBlack){
node2->mRight->mColor=nsNode::eBlack;
node2->mColor=nsNode::eRed;
ShiftLeft(*node2);
node2=node1->mParent->mLeft;
}
node2->mColor=node1->mParent->mColor;
node1->mParent->mColor=nsNode::eBlack;
node2->mLeft->mColor=nsNode::eBlack;
ShiftRight(*node1->mParent);
node1=mRoot;
} //else
} //if
} //while
node1->mColor=nsNode::eBlack;
return *this;
}
/**************************************************
Here comes the nsRBTreeIterator class...
*************************************************/
/**
*
*
* @update gess 4/11/98
* @param
* @return
*/
nsRBTreeIterator::nsRBTreeIterator(const nsRBTree& aTree) : mTree(aTree) {
}
/**
* copy constructor
*
* @update gess 4/11/98
* @param aCopy is the object you want to copy from
* @return newly constructed object
*/
nsRBTreeIterator::nsRBTreeIterator(const nsRBTreeIterator& aCopy) : mTree(aCopy.mTree) {
}
/**
* Destructor method
*
* @update gess 4/11/98
*/
nsRBTreeIterator::~nsRBTreeIterator(){
}
/**
* This method iterates over the tree, calling
* aFunctor for each node.
*
* @update gess 4/11/98
* @param aFunctor -- object to call for each node
* @param aNode -- node at which to start iteration
* @return this
*/
const nsRBTreeIterator& nsRBTreeIterator::ForEach(nsNodeFunctor& aFunctor) const{
mTree.ForEach(aFunctor);
return *this;
}

View File

@ -1,223 +0,0 @@
/**
* This file defines the binary tree class and its
* nsNode child class.
*
* This simple version stores nodes, and the
* nodes store void* ptrs.
*
* @update gess 4/11/98
* @param
* @return
*/
/**
* MODULE NOTES
* @update gess 4/11/98
*
* This file declares the nsRBTree (red/black tree).
* Red/black trees are auto-balancing binary trees.
*
* To use this class, define a subclass of nsNode
* which stores your data type. It's important that
* you overload the following methods:
*
* virtual PRBool operator<()
* virtual PRBool operator==()
*
*/
#ifndef _nsRBTree
#define _nsRBTree
#include "nsBTree.h"
/**
* Here comes the main event: our nsRBTree (red/black tree).
* Red/Black trees are autobalancing binary trees.
*
* @update gess4/20/98
*/
class NS_COM nsRBTree : public nsBTree {
public:
friend class NS_COM nsRBTreeIterator;
/**
* nsRBTree constructor
*
* @update gess 4/11/98
*/
nsRBTree();
/**
* nsRBTree constructor
*
* @update gess 4/11/98
*/
nsRBTree(const nsRBTree& aCopy);
/**
* nsRBTree destructor
*
* @update gess 4/11/98
*/
virtual ~nsRBTree();
/**
* Given a node, we're supposed to add it into
* our tree.
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* Add(nsNode& aNode);
/**
* Retrive the first node in the tree
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* First(void);
/**
* Retrieve the first node given a starting node
*
* @update gess 4/11/98
* @param aNode --
* @return node ptr or null
*/
nsNode* First(nsNode& aNode);
/**
* Find the last node in the tree
*
* @update gess 4/11/98
* @param
* @return node ptr or null
*/
nsNode* Last(void);
/**
* Find the last node from a given node
*
* @update gess 4/11/98
* @param aNode -- node ptr to start from
* @return node ptr or null
*/
nsNode* Last(nsNode& aNode);
/**
* Retrieve the node that preceeds the given node
*
* @update gess 4/11/98
* @param aNode -- node to find precedent of
* @return preceeding node ptr, or null
*/
nsNode* Before(nsNode& aNode);
/**
* Retrieve a ptr to the node following the given node
*
* @update gess 4/11/98
* @param aNode -- node to find successor node from
* @return node ptr or null
*/
nsNode* After(nsNode& aNode);
/**
* Find a (given) node in the tree
*
* @update gess 4/11/98
* @param node to find in the tree
* @return node ptr (if found) or null
*/
nsNode* Find(nsNode& aNode);
private:
/**
* Causes a shift to the left, to keep the
* underlying RB data in balance
*
* @update gess 4/11/98
* @param
* @return this
*/
nsRBTree& ShiftLeft(nsNode& aNode);
/**
* Causes a shift right to occur, to keep the
* underlying RB data in balance
*
* @update gess 4/11/98
* @param aNode -- node at which to perform shift
* @return this
*/
nsRBTree& ShiftRight(nsNode& aNode);
/**
* Rebalances tree around the given node. This only
* needs to be called after a node is deleted.
*
* @update gess 4/11/98
* @param aNode -- node to balance around
* @return this
*/
virtual nsBTree& ReBalance(nsNode& aNode);
};
class NS_COM nsRBTreeIterator {
public:
/**
* TreeIterator constructor
*
* @update gess 4/11/98
* @param
* @return
*/
nsRBTreeIterator(const nsRBTree& aTree);
/**
* TreeIterator constructor
*
* @update gess 4/11/98
* @param
* @return
*/
nsRBTreeIterator(const nsRBTreeIterator& aCopy);
/**
* tree iterator destructor
*
* @update gess 4/11/98
* @param
* @return
*/
~nsRBTreeIterator();
/**
* This method iterates over the tree, calling
* aFunctor for each node.
*
* @update gess 4/11/98
* @param aFunctor -- object to call for each node
* @param aNode -- node at which to start iteration
* @return this
*/
const nsRBTreeIterator& ForEach(nsNodeFunctor& aFunctor) const;
protected:
const nsRBTree& mTree;
};
#endif