730 lines
20 KiB
Plaintext
730 lines
20 KiB
Plaintext
|
////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// File name: splaytree.cxx
|
||
|
//
|
||
|
// Title: Splay Tree class
|
||
|
//
|
||
|
// Desciption:
|
||
|
//
|
||
|
// Author: Scott Holden (t-scotth)
|
||
|
//
|
||
|
// Date: August 16, 1994
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include <sysinc.h>
|
||
|
#include "splaytre.hxx"
|
||
|
|
||
|
template<class T>
|
||
|
void
|
||
|
SplayTree<T>::Splay(
|
||
|
SplayNode<T> *node
|
||
|
)
|
||
|
{
|
||
|
SplayNode<T> *Current = node;
|
||
|
SplayNode<T> *Parent;
|
||
|
SplayNode<T> *GrandParent;
|
||
|
|
||
|
while ( !IsRoot( Current ) ) {
|
||
|
Parent = Current->_Parent;
|
||
|
GrandParent = Parent->_Parent;
|
||
|
if ( IsLeftChild( Current ) ) {
|
||
|
if ( IsRoot( Parent ) ) {
|
||
|
//
|
||
|
// P C
|
||
|
// / \ / \
|
||
|
// C x ==> y P
|
||
|
// / \ / \
|
||
|
// y z z x
|
||
|
//
|
||
|
Parent->_LeftChild = Current->_RightChild;
|
||
|
if ( Parent->_LeftChild != NULL ) {
|
||
|
Parent->_LeftChild->_Parent = Parent;
|
||
|
}
|
||
|
Current->_RightChild = Parent;
|
||
|
_Root = Current;
|
||
|
Current->_Parent = NULL;
|
||
|
Parent->_Parent = Current;
|
||
|
}
|
||
|
else
|
||
|
if ( IsLeftChild( Parent ) ) {
|
||
|
//
|
||
|
// | |
|
||
|
// G C
|
||
|
// / \ / \
|
||
|
// P z ==> u P
|
||
|
// / \y / \
|
||
|
// C x G
|
||
|
// / \ / \
|
||
|
// u x y z
|
||
|
//
|
||
|
|
||
|
// connect Parent and x
|
||
|
Parent->_LeftChild = Current->_RightChild;
|
||
|
if ( Parent->_LeftChild != NULL ) {
|
||
|
Parent->_LeftChild->_Parent = Parent;
|
||
|
}
|
||
|
// connect GrandParent and y
|
||
|
GrandParent->_LeftChild = Parent->_RightChild;
|
||
|
if ( GrandParent->_LeftChild != NULL ) {
|
||
|
GrandParent->_LeftChild->_Parent = GrandParent;
|
||
|
}
|
||
|
// connect Current to Great GrandParent or assign as Root
|
||
|
if ( IsRoot( GrandParent ) ) {
|
||
|
_Root = Current;
|
||
|
Current->_Parent = NULL;
|
||
|
}
|
||
|
else {
|
||
|
Current->_Parent = GrandParent->_Parent;
|
||
|
if ( IsLeftChild( GrandParent ) ) {
|
||
|
Current->_Parent->_LeftChild = Current;
|
||
|
}
|
||
|
else { // GrandParent was a RightChild
|
||
|
Current->_Parent->_RightChild = Current;
|
||
|
}
|
||
|
}
|
||
|
// connect Current and Parent
|
||
|
Current->_RightChild = Parent;
|
||
|
Parent->_Parent = Current;
|
||
|
// connect Parent and GrandParent
|
||
|
Parent->_RightChild = GrandParent;
|
||
|
GrandParent->_Parent = Parent;
|
||
|
}
|
||
|
else { // else Parent is a RightChild
|
||
|
//
|
||
|
// | |
|
||
|
// G C
|
||
|
// / \ / \
|
||
|
// u P G P
|
||
|
// / \ ==> / \ / \
|
||
|
// C z u x y z
|
||
|
// / \
|
||
|
// x y
|
||
|
//
|
||
|
|
||
|
// connect GrandParent and x
|
||
|
GrandParent->_RightChild = Current->_LeftChild;
|
||
|
if ( GrandParent->_RightChild != NULL ) {
|
||
|
GrandParent->_RightChild->_Parent = GrandParent;
|
||
|
}
|
||
|
// connect Parent and y
|
||
|
Parent->_LeftChild = Current->_RightChild;
|
||
|
if ( Parent->_LeftChild != NULL ) {
|
||
|
Parent->_LeftChild->_Parent = Parent;
|
||
|
}
|
||
|
// connect Current and Great GrandParent or assign as Root
|
||
|
if ( IsRoot( GrandParent ) ) {
|
||
|
_Root = Current;
|
||
|
Current->_Parent = NULL;
|
||
|
}
|
||
|
else {
|
||
|
Current->_Parent = GrandParent->_Parent;
|
||
|
if ( IsLeftChild( GrandParent ) ) {
|
||
|
Current->_Parent->_LeftChild = Current;
|
||
|
}
|
||
|
else { // GrandParent was a RightChild
|
||
|
Current->_Parent->_RightChild = Current;
|
||
|
}
|
||
|
}
|
||
|
// connect Current to GrandParent
|
||
|
Current->_LeftChild = GrandParent;
|
||
|
GrandParent->_Parent = Current;
|
||
|
// connect Current to Parent
|
||
|
Current->_RightChild = Parent;
|
||
|
Parent->_Parent = Current;
|
||
|
}
|
||
|
}
|
||
|
else { // else Current is a RightChild
|
||
|
if ( IsRoot( Parent ) ){
|
||
|
//
|
||
|
// P C
|
||
|
// / \ / \
|
||
|
// x C ==> P z
|
||
|
// / \ / \
|
||
|
// y z x y
|
||
|
//
|
||
|
Parent->_RightChild = Current->_LeftChild;
|
||
|
if ( Parent->_RightChild != NULL ) {
|
||
|
Parent->_RightChild->_Parent = Parent;
|
||
|
}
|
||
|
Current->_LeftChild = Parent;
|
||
|
_Root = Current;
|
||
|
Current->_Parent = NULL;
|
||
|
Parent->_Parent = Current;
|
||
|
}
|
||
|
else
|
||
|
if ( IsRightChild( Parent ) ) {
|
||
|
//
|
||
|
// | |
|
||
|
// G C
|
||
|
// / \ / \
|
||
|
// u P P z
|
||
|
// / \ ==> / \
|
||
|
// x C G y
|
||
|
// / \ / \
|
||
|
// y z u x
|
||
|
//
|
||
|
// connect Parent and x
|
||
|
Parent->_RightChild = Current->_LeftChild;
|
||
|
if ( Parent->_RightChild != NULL ) {
|
||
|
Parent->_RightChild->_Parent = Parent;
|
||
|
}
|
||
|
// connect GrandParent and y
|
||
|
GrandParent->_RightChild = Parent->_LeftChild;
|
||
|
if ( GrandParent->_RightChild != NULL ) {
|
||
|
GrandParent->_RightChild->_Parent = GrandParent;
|
||
|
}
|
||
|
// connect Current to Great GrandParent or assign as Root
|
||
|
if ( IsRoot( GrandParent ) ) {
|
||
|
_Root = Current;
|
||
|
Current->_Parent = NULL;
|
||
|
}
|
||
|
else {
|
||
|
Current->_Parent = GrandParent->_Parent;
|
||
|
if ( IsLeftChild( GrandParent ) ) {
|
||
|
Current->_Parent->_LeftChild = Current;
|
||
|
}
|
||
|
else { // GrandParent was a RightChild
|
||
|
Current->_Parent->_RightChild = Current;
|
||
|
}
|
||
|
}
|
||
|
// connect Current and Parent
|
||
|
Current->_LeftChild = Parent;
|
||
|
Parent->_Parent = Current;
|
||
|
// connect Parent and GrandParent
|
||
|
Parent->_LeftChild = GrandParent;
|
||
|
GrandParent->_Parent = Parent;
|
||
|
}
|
||
|
else { // else Parent is a LeftChild
|
||
|
//
|
||
|
// | |
|
||
|
// G C
|
||
|
// / \ / \
|
||
|
// P z P G
|
||
|
// / \ ==> / \ / \
|
||
|
// u C u x y z
|
||
|
// / \
|
||
|
// x y
|
||
|
//
|
||
|
// connect GrandParent and x
|
||
|
GrandParent->_LeftChild = Current->_RightChild;
|
||
|
if ( GrandParent->_LeftChild != NULL ) {
|
||
|
GrandParent->_LeftChild->_Parent = GrandParent;
|
||
|
}
|
||
|
// connect Parent and y
|
||
|
Parent->_RightChild = Current->_LeftChild;
|
||
|
if ( Parent->_RightChild != NULL ) {
|
||
|
Parent->_RightChild->_Parent = Parent;
|
||
|
}
|
||
|
// connect Current and Great GrandParent or assign as Root
|
||
|
if ( IsRoot( GrandParent ) ) {
|
||
|
_Root = Current;
|
||
|
Current->_Parent = NULL;
|
||
|
}
|
||
|
else {
|
||
|
Current->_Parent = GrandParent->_Parent;
|
||
|
if ( IsLeftChild( GrandParent ) ) {
|
||
|
Current->_Parent->_LeftChild = Current;
|
||
|
}
|
||
|
else { // GrandParent was a RightChild
|
||
|
Current->_Parent->_RightChild = Current;
|
||
|
}
|
||
|
}
|
||
|
// connect Current to GrandParent
|
||
|
Current->_RightChild = GrandParent;
|
||
|
GrandParent->_Parent = Current;
|
||
|
// connect Current to Parent
|
||
|
Current->_LeftChild = Parent;
|
||
|
Parent->_Parent = Current;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template<class T>
|
||
|
void
|
||
|
SplayTree<T>::Delete(
|
||
|
SplayNode<T> * node
|
||
|
)
|
||
|
{
|
||
|
SplayNode<T> *x;
|
||
|
SplayNode<T> *y;
|
||
|
|
||
|
if ( node == NULL ) {
|
||
|
return;
|
||
|
}
|
||
|
if ( ( node->_RightChild == NULL ) ||
|
||
|
( node->_LeftChild == NULL ) ) {
|
||
|
y = node;
|
||
|
}
|
||
|
else {
|
||
|
y = Successor( node );
|
||
|
}
|
||
|
|
||
|
if ( y->_LeftChild != NULL ) {
|
||
|
x = y->_LeftChild;
|
||
|
}
|
||
|
else {
|
||
|
x = y->_RightChild;
|
||
|
}
|
||
|
|
||
|
if ( x != NULL ) {
|
||
|
x->_Parent = y->_Parent;
|
||
|
}
|
||
|
|
||
|
if ( y->_Parent == NULL ) {
|
||
|
_Root = x;
|
||
|
}
|
||
|
else if ( IsLeftChild( y ) ) {
|
||
|
y->_Parent->_LeftChild = x;
|
||
|
}
|
||
|
else {
|
||
|
y->_Parent->_RightChild = x;
|
||
|
}
|
||
|
|
||
|
if ( y != node ) {
|
||
|
node->_Data = y->_Data;
|
||
|
}
|
||
|
if ( y ) {
|
||
|
delete y;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// This function takes a pointer to two nodes. The parent node must
|
||
|
// be a member of the tree and must NOT have a right child. The child
|
||
|
// node must NOT be a current member of the tree, and must NOT
|
||
|
// already have a parent
|
||
|
//
|
||
|
template<class T>
|
||
|
SplayNode<T>*
|
||
|
SplayTree<T>::InsertAsRightChild(
|
||
|
SplayNode<T> *Parent,
|
||
|
SplayNode<T> *Child
|
||
|
)
|
||
|
{
|
||
|
if ( ( Parent == NULL ) || ( Child == NULL ) ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
if ( Parent->_RightChild == NULL ) {
|
||
|
Parent->_RightChild = Child;
|
||
|
Child->_Parent = Parent;
|
||
|
return Child;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// This function takes a pointer to two nodes. The parent node must
|
||
|
// be a member of the tree and must NOT have a left child. The child
|
||
|
// node must NOT be a current member of the tree, and must NOT
|
||
|
// already have a parent
|
||
|
//
|
||
|
template<class T>
|
||
|
SplayNode<T>*
|
||
|
SplayTree<T>::InsertAsLeftChild(
|
||
|
SplayNode<T> *Parent,
|
||
|
SplayNode<T> *Child
|
||
|
)
|
||
|
{
|
||
|
if ( ( Parent == NULL ) || ( Child == NULL ) ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
if ( Parent->_LeftChild == NULL ) {
|
||
|
Parent->_LeftChild = Child;
|
||
|
Child->_Parent = Parent;
|
||
|
return Child;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// The Successor takes an input to a node in the tree
|
||
|
// and returns a pointer to the successor of that
|
||
|
// node in the entire tree. If there is no successor
|
||
|
// a NULL value is returned.
|
||
|
//
|
||
|
template<class T>
|
||
|
SplayNode<T>*
|
||
|
SplayTree<T>::Successor(
|
||
|
SplayNode<T> *Node
|
||
|
)
|
||
|
{
|
||
|
if ( Node == NULL ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
// if a success exists in a subtree ...
|
||
|
SplayNode<T> *Temp = SubtreeSuccessor( Node );
|
||
|
|
||
|
if ( Temp ) {
|
||
|
return Temp;
|
||
|
}
|
||
|
// else there is no right child, so find the first
|
||
|
// ancestor that we are the left decendent of.
|
||
|
Temp = Node;
|
||
|
while (IsRightChild( Temp ) ) {
|
||
|
Temp = Temp->_Parent;
|
||
|
}
|
||
|
if ( IsLeftChild( Temp ) ) {
|
||
|
return Temp->_Parent;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// The Predecessor takes an input to a node in the tree
|
||
|
// and returns a pointer to the predecessor of that
|
||
|
// node in the entire tree. If there is no predecessor,
|
||
|
// a NULL value is returned.
|
||
|
//
|
||
|
template<class T>
|
||
|
SplayNode<T>*
|
||
|
SplayTree<T>::Predecessor(
|
||
|
SplayNode<T> *Node
|
||
|
)
|
||
|
{
|
||
|
if ( Node == NULL ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
// if a predecessor exists in the subtree
|
||
|
SplayNode<T> *Temp = SubtreePredecessor( Node );
|
||
|
|
||
|
if ( Temp ) {
|
||
|
return Temp;
|
||
|
}
|
||
|
// else there is no left child, so find the first
|
||
|
// ancestor that we are the right decendent of
|
||
|
Temp = Node;
|
||
|
while ( IsLeftChild( Temp ) ) {
|
||
|
Temp = Temp->_Parent;
|
||
|
}
|
||
|
if ( IsRightChild( Temp ) ) {
|
||
|
return Temp->_Parent;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// The SubtreePredecessor takes an input to a node in the tree
|
||
|
// and returns a pointer to the predecessor of a subtree
|
||
|
// rooted at the input node. If there is no predecessor, a
|
||
|
// NULL value is returned.
|
||
|
//
|
||
|
template<class T>
|
||
|
SplayNode<T>*
|
||
|
SplayTree<T>::SubtreePredecessor(
|
||
|
SplayNode<T> *Node
|
||
|
)
|
||
|
{
|
||
|
if ( Node == NULL ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
// the predecessor is the right-most node in the left sub-tree
|
||
|
SplayNode<T> *Temp = Node->_LeftChild;
|
||
|
|
||
|
if ( Temp != NULL ) {
|
||
|
while ( Temp->_RightChild != NULL ) {
|
||
|
Temp = Temp->_RightChild;
|
||
|
}
|
||
|
return Temp;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// The SubtreeSuccessor takes an input to a node in the tree
|
||
|
// and returns a pointer to the successor of a subtree
|
||
|
// rooted at the input node. If there is no successor, a
|
||
|
// NULL value is returned.
|
||
|
//
|
||
|
template<class T>
|
||
|
SplayNode<T>*
|
||
|
SplayTree<T>::SubtreeSuccessor(
|
||
|
SplayNode<T> *Node
|
||
|
)
|
||
|
{
|
||
|
if ( Node == NULL ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
// the successor is the left-most node in the right sub tree
|
||
|
SplayNode<T> *Temp = Node->_RightChild;
|
||
|
|
||
|
if ( Temp != NULL ) {
|
||
|
while ( Temp->_LeftChild != NULL ) {
|
||
|
Temp = Temp->_LeftChild;
|
||
|
}
|
||
|
return Temp;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
template<class T>
|
||
|
void
|
||
|
SplayTree<T>::Insert(
|
||
|
T *NewData
|
||
|
)
|
||
|
{
|
||
|
SplayNode<T> *Temp = NULL;
|
||
|
SplayNode<T> *TempRoot = _Root;
|
||
|
SplayNode<T> *NewNode = NULL;
|
||
|
|
||
|
while ( TempRoot != NULL ) {
|
||
|
Temp = TempRoot;
|
||
|
ASSERT( *( NewData ) != *( TempRoot->_Data ) );
|
||
|
//if ( *( NewData ) == *( TempRoot->_Data ) ) {
|
||
|
// return;
|
||
|
//}
|
||
|
if ( *( NewData ) < *( TempRoot->_Data ) ) {
|
||
|
TempRoot = TempRoot->_LeftChild;
|
||
|
}
|
||
|
//else {
|
||
|
else if ( *( NewData ) > *( TempRoot->_Data ) ) {
|
||
|
TempRoot = TempRoot->_RightChild;
|
||
|
}
|
||
|
else return; // *NewData == *TempRoot->_Data
|
||
|
}
|
||
|
if ( Temp == NULL ) {
|
||
|
_Root = new SplayNode<T>( NewData );
|
||
|
}
|
||
|
else
|
||
|
if ( *( NewData ) < *( Temp->_Data ) ) {
|
||
|
NewNode = InsertAsLeftChild( Temp, new SplayNode<T>( NewData ) );
|
||
|
Splay( NewNode );
|
||
|
}
|
||
|
else {
|
||
|
NewNode = InsertAsRightChild( Temp, new SplayNode<T>( NewData ) );
|
||
|
Splay( NewNode );
|
||
|
}
|
||
|
_Size++;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Given an element, find the element in the tree
|
||
|
// (if it exists) and return a pointer to the element.
|
||
|
// If the element is not found, then the return
|
||
|
// value is NULL.
|
||
|
//
|
||
|
template<class T>
|
||
|
T*
|
||
|
SplayTree<T>::Find(
|
||
|
T *FindData
|
||
|
)
|
||
|
{
|
||
|
if ( FindData == NULL ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
SplayNode<T> *DataNode = Find( _Root, FindData );
|
||
|
if ( DataNode == NULL ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
Splay( DataNode );
|
||
|
return ( DataNode->_Data );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Given a pointer to a node (which is the root of a
|
||
|
// subtree) and a pointer to an element, determine
|
||
|
// if the element exists in the tree.
|
||
|
// If the element exist, return a pointer to the node
|
||
|
// containing such an element, or return a NULL.
|
||
|
//
|
||
|
template<class T>
|
||
|
SplayNode<T>*
|
||
|
SplayTree<T>::Find(
|
||
|
SplayNode<T> *SubRoot,
|
||
|
T *FindData
|
||
|
)
|
||
|
{
|
||
|
//if ( ( SubRoot == NULL ) ||
|
||
|
// ( *( FindData ) == *( SubRoot->_Data ) ) ) {
|
||
|
// return SubRoot;
|
||
|
//}
|
||
|
if ( !SubRoot ) {
|
||
|
return SubRoot;
|
||
|
}
|
||
|
if ( *( FindData ) < *( SubRoot->_Data ) ) {
|
||
|
return Find( SubRoot->_LeftChild, FindData );
|
||
|
}
|
||
|
else if ( *( FindData ) > * ( SubRoot->_Data ) ) {
|
||
|
return Find( SubRoot->_RightChild, FindData );
|
||
|
}
|
||
|
else return SubRoot; // *FindData == *SubRoot->_Data
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Given an element, find the element in the tree
|
||
|
// (if it exists) and delete the element from the
|
||
|
// tree. The function returns a pointer to the
|
||
|
// element. If the element is not found, then
|
||
|
// the return value is NULL.
|
||
|
//
|
||
|
template<class T>
|
||
|
T*
|
||
|
SplayTree<T>::Delete(
|
||
|
T *DeleteData
|
||
|
)
|
||
|
{
|
||
|
SplayNode<T> *DeleteNode = Find( _Root, DeleteData );
|
||
|
// must copy the data out of the node, since a Delete( ..)
|
||
|
// is allowed to change the data within the node
|
||
|
T *Data = DeleteNode->_Data;
|
||
|
if ( DeleteNode ) {
|
||
|
Delete( DeleteNode );
|
||
|
_Size--;
|
||
|
return Data;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Find the node in the tree with the smallest value,
|
||
|
// and return a pointer to such a node.
|
||
|
// If there are no nodes in the tree, return a NULL.
|
||
|
//
|
||
|
template<class T>
|
||
|
SplayNode<T>*
|
||
|
SplayTree<T>::MinimumNode( )
|
||
|
{
|
||
|
SplayNode<T> *SubRoot = _Root;
|
||
|
|
||
|
if ( _Root == NULL ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
while ( SubRoot->_LeftChild != NULL ) {
|
||
|
SubRoot = SubRoot->_LeftChild;
|
||
|
}
|
||
|
return SubRoot;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Find the node in the tree with the largest value.
|
||
|
// and return a pointer to such a node.
|
||
|
// If there are no nodes in the tree, return a NULL.
|
||
|
//
|
||
|
template<class T>
|
||
|
SplayNode<T>*
|
||
|
SplayTree<T>::MaximumNode( )
|
||
|
{
|
||
|
SplayNode<T> *SubRoot = _Root;
|
||
|
|
||
|
if ( _Root == NULL ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
while ( SubRoot->_RightChild != NULL ) {
|
||
|
SubRoot = SubRoot->_RightChild;
|
||
|
}
|
||
|
return SubRoot;
|
||
|
}
|
||
|
|
||
|
template<class T>
|
||
|
T*
|
||
|
SplayTree<T>::Successor( T *Data )
|
||
|
{
|
||
|
SplayNode<T> *DataNode;
|
||
|
SplayNode<T> *SuccNode;
|
||
|
|
||
|
if ( Data ) {
|
||
|
DataNode = Find( _Root, Data );
|
||
|
if ( DataNode ) {
|
||
|
SuccNode = Successor( DataNode );
|
||
|
if ( SuccNode ) {
|
||
|
Splay( SuccNode );
|
||
|
return SuccNode->_Data;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
template<class T>
|
||
|
T*
|
||
|
SplayTree<T>::Predecessor( T *Data )
|
||
|
{
|
||
|
SplayNode<T> *DataNode;
|
||
|
SplayNode<T> *PredNode;
|
||
|
|
||
|
if ( Data ) {
|
||
|
DataNode = Find( _Root, Data );
|
||
|
if ( DataNode ) {
|
||
|
PredNode = Predecessor( DataNode );
|
||
|
if ( PredNode ) {
|
||
|
Splay( PredNode );
|
||
|
return PredNode->_Data;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
#ifdef DEBUGRPC
|
||
|
|
||
|
template<class T>
|
||
|
void
|
||
|
SplayTree<T>::Print()
|
||
|
{
|
||
|
if ( _Root == NULL ) {
|
||
|
return;
|
||
|
}
|
||
|
Print( _Root );
|
||
|
}
|
||
|
|
||
|
template<class T>
|
||
|
void
|
||
|
SplayTree<T>::Print( SplayNode<T> *TempRoot )
|
||
|
{
|
||
|
if ( TempRoot == NULL ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Print( TempRoot->_LeftChild );
|
||
|
|
||
|
if ( IsLeftChild( TempRoot ) ) {
|
||
|
if ( *( TempRoot->_Parent->_Data ) < *( TempRoot->_Data ) ) {
|
||
|
cout << "Bastard tree! ";
|
||
|
}
|
||
|
else cout << "OK ";
|
||
|
}
|
||
|
else
|
||
|
if ( IsRightChild( TempRoot ) ) {
|
||
|
if ( *( TempRoot->_Parent->_Data ) > *( TempRoot->_Data ) ) {
|
||
|
cout << "Bastard tree! ";
|
||
|
}
|
||
|
else cout << "OK ";
|
||
|
}
|
||
|
cout << *( TempRoot->_Data ) << " \n";
|
||
|
|
||
|
Print( TempRoot->_RightChild );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
template<class T>
|
||
|
unsigned int
|
||
|
SplayTree<T>::Depth( SplayNode<T> *TempRoot, unsigned int CurrentDepth )
|
||
|
{
|
||
|
unsigned int right = 0;
|
||
|
unsigned int left = 0;
|
||
|
if ( TempRoot->_RightChild ) {
|
||
|
right = Depth( TempRoot->_RightChild, CurrentDepth + 1 );
|
||
|
}
|
||
|
if ( TempRoot->_LeftChild ) {
|
||
|
left = Depth( TempRoot->_LeftChild, CurrentDepth + 1 );
|
||
|
}
|
||
|
if ( ( right > left ) && ( right > CurrentDepth ) ) {
|
||
|
return right;
|
||
|
}
|
||
|
else
|
||
|
if ( (left > right ) && ( left > CurrentDepth ) ) {
|
||
|
return left;
|
||
|
}
|
||
|
return ( CurrentDepth + 1 );
|
||
|
}
|
||
|
|
||
|
#endif // DEBUGRPC
|