1994-11-04 16:29:24 +00:00
|
|
|
|
/* Implementation for Objective-C BinaryTree collection object
|
1996-02-22 15:11:43 +00:00
|
|
|
|
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
|
|
|
|
|
Date: May 1993
|
|
|
|
|
|
1996-04-17 19:55:26 +00:00
|
|
|
|
This file is part of the Gnustep Base Library.
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
1996-04-17 15:23:00 +00:00
|
|
|
|
#include <gnustep/base/BinaryTree.h>
|
|
|
|
|
#include <gnustep/base/IndexedCollectionPrivate.h>
|
|
|
|
|
#include <gnustep/base/BinaryTreeNode.h>
|
|
|
|
|
#include <gnustep/base/NSString.h>
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* the sentinal */
|
1994-11-04 16:29:24 +00:00
|
|
|
|
static id nilBinaryTreeNode;
|
|
|
|
|
|
|
|
|
|
@implementation BinaryTree
|
|
|
|
|
|
1995-03-12 19:57:15 +00:00
|
|
|
|
+ (void) initialize
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
if (self == [BinaryTree class])
|
|
|
|
|
{
|
|
|
|
|
nilBinaryTreeNode = [[BinaryTreeNode alloc] init];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This is the designated initializer of this class */
|
|
|
|
|
- init
|
|
|
|
|
{
|
|
|
|
|
_count = 0;
|
|
|
|
|
_contents_root = [self nilNode];
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Archiving must mimic the above designated initializer */
|
|
|
|
|
|
1995-06-28 23:50:13 +00:00
|
|
|
|
/* xxx See Collection _decodeContentsWithCoder:.
|
|
|
|
|
We shouldn't do an -addElement. finishEncodingInterconnectedObjects
|
|
|
|
|
should take care of all that. */
|
|
|
|
|
|
1995-04-09 01:53:53 +00:00
|
|
|
|
- _initCollectionWithCoder: aCoder
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1995-06-28 23:50:13 +00:00
|
|
|
|
[self notImplemented:_cmd];
|
1995-04-09 01:53:53 +00:00
|
|
|
|
[super _initCollectionWithCoder:aCoder];
|
|
|
|
|
_count = 0;
|
|
|
|
|
_contents_root = [self nilNode];
|
|
|
|
|
return self;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-01-24 03:16:05 +00:00
|
|
|
|
- (void) _encodeContentsWithCoder: (id <Encoding>)aCoder
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
[aCoder startEncodingInterconnectedObjects];
|
|
|
|
|
[super _encodeContentsWithCoder:aCoder];
|
|
|
|
|
[aCoder finishEncodingInterconnectedObjects];
|
|
|
|
|
}
|
|
|
|
|
|
1996-01-24 03:16:05 +00:00
|
|
|
|
- (void) _decodeContentsWithCoder: (id <Decoding>)aCoder
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
[aCoder startDecodingInterconnectedObjects];
|
|
|
|
|
[super _decodeContentsWithCoder:aCoder];
|
|
|
|
|
[aCoder finishDecodingInterconnectedObjects];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Empty copy must empty an allocCopy'ed version of self */
|
|
|
|
|
- emptyCopy
|
|
|
|
|
{
|
|
|
|
|
BinaryTree *copy = [super emptyCopy];
|
|
|
|
|
copy->_count = 0;
|
|
|
|
|
copy->_contents_root = [self nilNode];
|
|
|
|
|
return copy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This must work without sending any messages to content objects */
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) _empty
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
_count = 0;
|
|
|
|
|
_contents_root = [self nilNode];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- nilNode
|
|
|
|
|
{
|
|
|
|
|
return nilBinaryTreeNode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- rootNode
|
|
|
|
|
{
|
|
|
|
|
return _contents_root;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- leftmostNodeFromNode: aNode
|
|
|
|
|
{
|
|
|
|
|
id left;
|
|
|
|
|
|
|
|
|
|
if (aNode && aNode != [self nilNode])
|
|
|
|
|
{
|
|
|
|
|
while ((left = [aNode leftNode]) != [self nilNode])
|
|
|
|
|
aNode = left;
|
|
|
|
|
}
|
|
|
|
|
return aNode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- rightmostNodeFromNode: aNode
|
|
|
|
|
{
|
|
|
|
|
id right;
|
|
|
|
|
|
|
|
|
|
if (aNode && aNode != [self nilNode])
|
|
|
|
|
while ((right = [aNode rightNode]) != [self nilNode])
|
|
|
|
|
{
|
|
|
|
|
aNode = right;
|
|
|
|
|
}
|
|
|
|
|
return aNode;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- firstObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return [self leftmostNodeFromNode: _contents_root];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- lastObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return [self rightmostNodeFromNode: _contents_root];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* This is correct only if the tree is sorted. How to deal with this? */
|
|
|
|
|
- maxObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return [self rightmostNodeFromNode: _contents_root];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This is correct only is the tree is sorted. How to deal with this? */
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- minObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return [self leftmostNodeFromNode: _contents_root];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- successorOfObject: anObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
id tmp;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Make sure we actually own the anObject. */
|
|
|
|
|
assert ([anObject binaryTree] == self);
|
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
// here tmp is the right node;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ((tmp = [anObject rightNode]) != [self nilNode])
|
|
|
|
|
return [self leftmostNodeFromNode: tmp];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
// here tmp is the parent;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
tmp = [anObject parentNode];
|
|
|
|
|
while (tmp != [self nilNode] && anObject == [tmp rightNode])
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
anObject = tmp;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
tmp = [tmp parentNode];
|
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if (tmp == [self nilNode])
|
|
|
|
|
return NO_OBJECT;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// I should make sure that [_contents_root parentNode] == [self nilNode];
|
|
|
|
|
// Perhaps I should make [_contents_root parentNode] == binaryTreeObj ??;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- predecessorObject: anObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
id tmp;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Make sure we actually own the anObject. */
|
|
|
|
|
assert ([anObject binaryTree] == self);
|
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
// here tmp is the left node;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ((tmp = [anObject leftNode]) != [self nilNode])
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return [self rightmostNodeFromNode:tmp];
|
|
|
|
|
// here tmp is the parent;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
tmp = [anObject parentNode];
|
|
|
|
|
while (tmp != [self nilNode] && anObject == [tmp leftNode])
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
anObject = tmp;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
tmp = [tmp parentNode];
|
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if (tmp == [self nilNode])
|
|
|
|
|
return NO_OBJECT;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This relies on [_contents_root parentNode] == [self nilNode] */
|
|
|
|
|
- rootFromNode: aNode
|
|
|
|
|
{
|
|
|
|
|
id parentNode;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
/* Make sure we actually own the aNode. */
|
|
|
|
|
assert ([aNode binaryTree] == self);
|
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
while ((parentNode = [aNode parentNode]) != [self nilNode])
|
|
|
|
|
aNode = parentNode;
|
|
|
|
|
return aNode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This relies on [_contents_root parentNode] == [self nilNode] */
|
|
|
|
|
- (unsigned) depthOfNode: aNode
|
|
|
|
|
{
|
|
|
|
|
unsigned count = 0;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Make sure we actually own the aNode. */
|
|
|
|
|
assert ([aNode binaryTree] == self);
|
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
if (aNode == nil || aNode == [self nilNode])
|
|
|
|
|
[self error:"in %s, Can't find depth of nil node", sel_get_name(_cmd)];
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
aNode = [aNode parentNode];
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
while (aNode != [self nilNode]);
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (unsigned) heightOfNode: aNode
|
|
|
|
|
{
|
|
|
|
|
unsigned leftHeight, rightHeight;
|
|
|
|
|
id tmpNode;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Make sure we actually own the aNode. */
|
|
|
|
|
assert ([aNode binaryTree] == self);
|
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
if (aNode == nil || aNode == [self nilNode])
|
|
|
|
|
{
|
|
|
|
|
[self error:"in %s, Can't find height of nil node", sel_get_name(_cmd)];
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
leftHeight = ((tmpNode = [aNode leftNode])
|
|
|
|
|
?
|
|
|
|
|
(1 + [self heightOfNode:tmpNode])
|
|
|
|
|
:
|
|
|
|
|
0);
|
|
|
|
|
rightHeight = ((tmpNode = [aNode rightNode])
|
|
|
|
|
?
|
|
|
|
|
(1 + [self heightOfNode:tmpNode])
|
|
|
|
|
:
|
|
|
|
|
0);
|
|
|
|
|
return MAX(leftHeight, rightHeight);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (unsigned) nodeCountUnderNode: aNode
|
|
|
|
|
{
|
|
|
|
|
unsigned count = 0;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
/* Make sure we actually own the aNode. */
|
|
|
|
|
assert ([aNode binaryTree] == self);
|
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
if ([aNode leftNode] != [self nilNode])
|
|
|
|
|
count += 1 + [self nodeCountUnderNode:[aNode leftNode]];
|
|
|
|
|
if ([aNode rightNode] != [self nilNode])
|
|
|
|
|
count += 1 + [self nodeCountUnderNode:[aNode rightNode]];
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- leftRotateAroundNode: aNode
|
|
|
|
|
{
|
|
|
|
|
id y;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Make sure we actually own the aNode. */
|
|
|
|
|
assert ([aNode binaryTree] == self);
|
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
y = [aNode rightNode];
|
|
|
|
|
if (y == [self nilNode])
|
|
|
|
|
return self;
|
|
|
|
|
[aNode setRightNode:[y leftNode]];
|
|
|
|
|
if ([y leftNode] != [self nilNode])
|
|
|
|
|
[[y leftNode] setParentNode:aNode];
|
|
|
|
|
[y setParentNode:[aNode parentNode]];
|
|
|
|
|
if ([aNode parentNode] == [self nilNode])
|
|
|
|
|
_contents_root = y;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (NODE_IS_LEFTCHILD(aNode))
|
|
|
|
|
[[aNode parentNode] setLeftNode:y];
|
|
|
|
|
else
|
|
|
|
|
[[aNode parentNode] setRightNode:y];
|
|
|
|
|
}
|
|
|
|
|
[y setLeftNode:aNode];
|
|
|
|
|
[aNode setParentNode:y];
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- rightRotateAroundNode: aNode
|
|
|
|
|
{
|
|
|
|
|
id y;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Make sure we actually own the aNode. */
|
|
|
|
|
assert ([aNode binaryTree] == self);
|
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
y = [aNode leftNode];
|
|
|
|
|
if (y == [self nilNode])
|
|
|
|
|
return self;
|
|
|
|
|
[aNode setLeftNode:[y rightNode]];
|
|
|
|
|
if ([y rightNode] != [self nilNode])
|
|
|
|
|
[[y rightNode] setParentNode:aNode];
|
|
|
|
|
[y setParentNode:[aNode parentNode]];
|
|
|
|
|
if ([aNode parentNode] == [self nilNode])
|
|
|
|
|
_contents_root = y;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (NODE_IS_RIGHTCHILD(aNode))
|
|
|
|
|
[[aNode parentNode] setRightNode:y];
|
|
|
|
|
else
|
|
|
|
|
[[aNode parentNode] setLeftNode:y];
|
|
|
|
|
}
|
|
|
|
|
[y setRightNode:aNode];
|
|
|
|
|
[aNode setParentNode:y];
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- objectAtIndex: (unsigned)index
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id ret;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
CHECK_INDEX_RANGE_ERROR(index, _count);
|
1996-02-22 15:11:43 +00:00
|
|
|
|
ret = [self firstObject];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
// Not very efficient; Should be rewritten;
|
|
|
|
|
while (index--)
|
1996-02-22 15:11:43 +00:00
|
|
|
|
ret = [self successorOfObject: ret];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) sortAddObject: newObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
id theParent, tmpChild;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Make sure no one else already owns the newObject. */
|
|
|
|
|
assert ([newObject binaryTree] == NO_OBJECT);
|
|
|
|
|
|
|
|
|
|
/* Claim ownership of the newObject. */
|
|
|
|
|
[newObject retain];
|
|
|
|
|
[newObject setBinaryTree: self];
|
|
|
|
|
|
|
|
|
|
[newObject setLeftNode:[self nilNode]];
|
|
|
|
|
[newObject setRightNode:[self nilNode]];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
theParent = [self nilNode];
|
|
|
|
|
tmpChild = _contents_root;
|
|
|
|
|
while (tmpChild != [self nilNode])
|
|
|
|
|
{
|
|
|
|
|
theParent = tmpChild;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ([newObject compare: theParent] < 0)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
tmpChild = [tmpChild leftNode];
|
|
|
|
|
else
|
|
|
|
|
tmpChild = [tmpChild rightNode];
|
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[newObject setParentNode:theParent];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
if (theParent == [self nilNode])
|
1996-02-22 15:11:43 +00:00
|
|
|
|
_contents_root = newObject;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ([newObject compare: theParent] < 0)
|
|
|
|
|
[theParent setLeftNode:newObject];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
else
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[theParent setRightNode:newObject];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
_count++;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) addObject: newObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
// By default insert in sorted order.
|
|
|
|
|
[self sortAddObject: newObject];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) removeObject: oldObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
id x, y;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Make sure we actually own the aNode. */
|
|
|
|
|
assert ([oldObject binaryTree] == self);
|
|
|
|
|
|
|
|
|
|
/* Extract the oldObject and sew up the cut. */
|
|
|
|
|
if ([oldObject leftNode] == [self nilNode]
|
|
|
|
|
|| [oldObject rightNode] == [self nilNode])
|
|
|
|
|
y = oldObject;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
else
|
1996-02-22 15:11:43 +00:00
|
|
|
|
y = [self successorOfObject: oldObject];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
if ([y leftNode] != [self nilNode])
|
|
|
|
|
x = [y leftNode];
|
|
|
|
|
else
|
|
|
|
|
x = [y rightNode];
|
|
|
|
|
|
1995-04-12 15:34:39 +00:00
|
|
|
|
if (x != [self nilNode])
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[x setParentNode: [y parentNode]];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
if ([y parentNode] == [self nilNode])
|
|
|
|
|
_contents_root = x;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (y == [[y parentNode] leftNode])
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[[y parentNode] setLeftNode: x];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
else
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[[y parentNode] setRightNode: x];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if (y != oldObject)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* put y in the place of oldObject */
|
|
|
|
|
[y setParentNode: [oldObject parentNode]];
|
|
|
|
|
[y setLeftNode: [oldObject leftNode]];
|
|
|
|
|
[y setRightNode: [oldObject rightNode]];
|
|
|
|
|
if (oldObject == [[oldObject parentNode] leftNode])
|
|
|
|
|
[[oldObject parentNode] setLeftNode: y];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
else
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[[oldObject parentNode] setRightNode: y];
|
|
|
|
|
[[oldObject leftNode] setParentNode: y];
|
|
|
|
|
[[oldObject rightNode] setParentNode: y];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
_count--;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Release ownership of the object. */
|
|
|
|
|
#if 0
|
|
|
|
|
[oldObject setRightNode: [self nilNode]];
|
|
|
|
|
[oldObject setLeftNode: [self nilNode]];
|
|
|
|
|
[oldObject setParentNode: [self nilNode]];
|
|
|
|
|
#else
|
|
|
|
|
[oldObject setLeftNode: NO_OBJECT];
|
|
|
|
|
[oldObject setRightNode: NO_OBJECT];
|
|
|
|
|
[oldObject setParentNode: NO_OBJECT];
|
|
|
|
|
#endif
|
|
|
|
|
[oldObject setBinaryTree: NO_OBJECT];
|
|
|
|
|
[oldObject release];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
// ENUMERATING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- nextObjectWithEnumState: (void**)enumState
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
if (!(*enumState))
|
|
|
|
|
*enumState = [self leftmostNodeFromNode:_contents_root];
|
|
|
|
|
else
|
1996-02-22 15:11:43 +00:00
|
|
|
|
*enumState = [self successorOfObject:*enumState];
|
|
|
|
|
return (id) *enumState;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- prevObjectWithEnumState: (void**)enumState
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
if (!(*enumState))
|
|
|
|
|
*enumState = [self rightmostNodeFromNode:_contents_root];
|
|
|
|
|
else
|
1996-02-22 15:11:43 +00:00
|
|
|
|
*enumState = [self predecessorObject:*enumState];
|
|
|
|
|
return (id) *enumState;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (unsigned) count
|
|
|
|
|
{
|
|
|
|
|
return _count;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
/* replace this with something better eventually */
|
|
|
|
|
- _tmpPrintFromNode: aNode indent: (int)count
|
|
|
|
|
{
|
|
|
|
|
printf("%-*s", count, "");
|
1996-02-22 15:11:43 +00:00
|
|
|
|
printf("%s\n", [[aNode description] cStringNoCopy]);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
printf("%-*s.", count, "");
|
|
|
|
|
if ([aNode leftNode] != [self nilNode])
|
|
|
|
|
[self _tmpPrintFromNode:[aNode leftNode] indent:count+2];
|
|
|
|
|
else
|
|
|
|
|
printf("\n");
|
|
|
|
|
printf("%-*s.", count, "");
|
|
|
|
|
if ([aNode rightNode] != [self nilNode])
|
|
|
|
|
[self _tmpPrintFromNode:[aNode rightNode] indent:count+2];
|
|
|
|
|
else
|
|
|
|
|
printf("\n");
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- binaryTreePrintForDebugger
|
|
|
|
|
{
|
|
|
|
|
[self _tmpPrintFromNode:_contents_root indent:0];
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
/* These methods removed because they belong to an
|
|
|
|
|
OrderedCollection implementation, not an IndexedCollection
|
|
|
|
|
implementation. */
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
// NOTE: This gives you the power to put elements in unsorted order;
|
|
|
|
|
- insertObject: newObject before: oldObject
|
|
|
|
|
{
|
|
|
|
|
id tmp;
|
|
|
|
|
|
|
|
|
|
/* Make sure no one else already owns the newObject. */
|
|
|
|
|
assert ([newObject linkedList] == NO_OBJECT);
|
|
|
|
|
|
|
|
|
|
/* Claim ownership of the newObject. */
|
|
|
|
|
[newObject retain];
|
|
|
|
|
[newObject setBinaryTree: self];
|
|
|
|
|
|
|
|
|
|
[newObject setRightNode:[self nilNode]];
|
|
|
|
|
[newObject setLeftNode:[self nilNode]];
|
|
|
|
|
if ((tmp = [oldObject leftNode]) != [self nilNode])
|
|
|
|
|
{
|
|
|
|
|
[(tmp = [self rightmostNodeFromNode:tmp]) setRightNode:newObject];
|
|
|
|
|
[newObject setParentNode:tmp];
|
|
|
|
|
}
|
|
|
|
|
else if (newObject != [self nilNode])
|
|
|
|
|
{
|
|
|
|
|
[oldObject setLeftNode:newObject];
|
|
|
|
|
[newObject setParentNode:oldObject];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_contents_root = newObject;
|
|
|
|
|
[newObject setParentNode:[self nilNode]];
|
|
|
|
|
}
|
|
|
|
|
_count++;
|
|
|
|
|
RETAIN_ELT(newObject);
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NOTE: This gives you the power to put elements in unsorted order;
|
|
|
|
|
- insertObject: newObject after: oldObject
|
|
|
|
|
{
|
|
|
|
|
id tmp;
|
|
|
|
|
|
|
|
|
|
/* Make sure no one else already owns the newObject. */
|
|
|
|
|
assert ([newObject linkedList] == NO_OBJECT);
|
|
|
|
|
|
|
|
|
|
/* Claim ownership of the newObject. */
|
|
|
|
|
[newObject retain];
|
|
|
|
|
[newObject setBinaryTree: self];
|
|
|
|
|
|
|
|
|
|
[newObject setRightNode:[self nilNode]];
|
|
|
|
|
[newObject setLeftNode:[self nilNode]];
|
|
|
|
|
if ((tmp = [oldObject rightNode]) != [self nilNode])
|
|
|
|
|
{
|
|
|
|
|
[(tmp = [self leftmostNodeFromNode:tmp]) setLeftNode:newObject];
|
|
|
|
|
[newObject setParentNode:tmp];
|
|
|
|
|
}
|
|
|
|
|
else if (newObject != [self nilNode])
|
|
|
|
|
{
|
|
|
|
|
[oldObject setRightNode:newObject];
|
|
|
|
|
[newObject setParentNode:oldObject];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_contents_root = newObject;
|
|
|
|
|
[newObject setParentNode:[self nilNode]];
|
|
|
|
|
}
|
|
|
|
|
_count++;
|
|
|
|
|
RETAIN_ELT(newObject);
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NOTE: This gives you the power to put elements in unsorted order;
|
|
|
|
|
- insertObject: newObject atIndex: (unsigned)index
|
|
|
|
|
{
|
|
|
|
|
CHECK_INDEX_RANGE_ERROR(index, _count+1);
|
|
|
|
|
|
|
|
|
|
if (index == _count)
|
|
|
|
|
[self appendObject:newObject];
|
|
|
|
|
else
|
|
|
|
|
[self insertObject:newObject before:[self ObjectAtIndex:index]];
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NOTE: This gives you the power to put elements in unsorted order;
|
|
|
|
|
- appendObject: newObject
|
|
|
|
|
{
|
|
|
|
|
if (_count == 0)
|
|
|
|
|
{
|
|
|
|
|
/* Make sure no one else already owns the newObject. */
|
|
|
|
|
assert ([newObject linkedList] == NO_OBJECT);
|
|
|
|
|
|
|
|
|
|
/* Claim ownership of the newObject. */
|
|
|
|
|
[newObject retain];
|
|
|
|
|
[newObject setBinaryTree: self];
|
|
|
|
|
|
|
|
|
|
_contents_root = newObject;
|
|
|
|
|
_count = 1;
|
|
|
|
|
[newObject setLeftNode:[self nilNode]];
|
|
|
|
|
[newObject setRightNode:[self nilNode]];
|
|
|
|
|
[newObject setParentNode:[self nilNode]];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
[self insertObject:newObject after:[self lastObject]];
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
#endif
|