frustrated_intern has asked for the wisdom of the Perl Monks concerning the following question:
here's the situation:
after i delete a node, and modify the necessary parent/child pointers, my tree becomes corrupted, and several nodes near the region where a node was deleted as a result of the delete function call lose their parent pointers.
at the end of my delete function (displayed below) i return my "successor" node (the smallest node larger than the node being deleted). if the deleted node doesn't have a left or right child, this "successor" node is the node itself. in this situation, once i exit the delete function, i lose information about the parent pointers for the nodes to the left or right of the deleted node (which are moved up, and become the children of the deleted node's parent). instead, their parent pointers are set to undefined.
here's the interesting part: at the end of my delete function, i return the successor node (referred to as $curr). if i have a receiver for the returned $curr node outside of my program, everything works fine. it's just that when there is no receiver (hence $curr is garbage collected) that the tree becomes corrupted. this is strange, because the new pointers set after the node is deleted don't intersect with the returned node.
any hints on how to fix this? both my mentor and i are officially stumped. thanks!
- frustrated_intern
code shown below:
sub RBDelete{ my($self, $key) = @_; if($self->isEmpty){ #empty tree die "Illegal Operation 4: Cannot delete without first insertin +g."; } my $node = $self->RBSearch($key); #find node in tree if(!(defined $node)){ #non-inserted node die "Illegal Operation 5: Cannot delete node without first ins +erting it."; } if($node->equals($self->{_root}) == 1) && $node->isLeaf){ $self->{_root} = ref($node); return; } my $curr; my $temp; if(!($node->hasLeft) || !($node->hasRight)){ $curr = $node; }else{ $curr = $node->mySuccessor; #successor node -- } if($curr->hasLeft){ $temp = $curr->getLeft; }elsif($curr->hasRight){ $temp = $curr->getRight; }else{ $temp = $self->{_sentinel_node}; #set up sentinel node as "dum +my node" } my $currP = $curr->getParent; if($node->isRoot){ $self->{_root}->markRoot(0); $self->{_root} = $temp; $temp->markRoot(1); }elsif($curr->equals($curr->getParent->getLeft)){ #curr is left ch +ild if(defined $temp->getNodeKey){ #set temp to cur's parent $currP->setLeft($temp); }else{ $currP->removeLeft; } }else{ if(defined $temp->getNodeKey){ #curr is right child $currP->mySetRight($temp); #set temp as curr's parent's r +ight child }else{ $currP->removeRight; } } my $currColor = $curr->getNodeColor; if($curr->equals($node) == 0){ #curr and node distinct nodes -- sh +ift curr up to node's position my $nodeRight = $node->getRight; my $nodeLeft = $node->getLeft; $node->{_right} = undef; $node->{_left} = undef; if($node->isRoot){ $self->{_root}->markRoot(0); $curr->markRoot(1); $self->{_root} = $curr; }else{ if($node->equals($node->getParent->getLeft)){ $node->getParent->setLeft($curr); }else{ $node->getParent->setRight($curr); } } if(defined $nodeRight){ $curr->setRight($nodeRight); } if(defined $nodeLeft){ $curr->setLeft($nodeLeft); } $curr->setNodeColor($node->getNodeColor); } if($currColor == 0){ $self->RBDeleteFix($temp); } return $curr; }
Edit g0n: closed b tag after "here's the situation"
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: help! red-black binary tree problem
by Ovid (Cardinal) on Jul 23, 2005 at 01:45 UTC | |
by ikegami (Patriarch) on Jul 23, 2005 at 07:15 UTC | |
|
Re: help! red-black binary tree problem
by Daedalus207 (Novice) on Jul 23, 2005 at 07:36 UTC | |
by frustrated_intern (Initiate) on Jul 25, 2005 at 17:56 UTC | |
|
You probably want a hash.
by schwern (Scribe) on Jul 23, 2005 at 19:55 UTC |