/* A red-black tree implementation for building minisegs. Copyright (C) 2002-2006 Randy Heit This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "zdbsp.h" #include "nodebuild.h" FEventTree::FEventTree () : Root (&Nil), Spare (NULL) { memset (&Nil, 0, sizeof(Nil)); } FEventTree::~FEventTree () { FEvent *probe; DeleteAll (); probe = Spare; while (probe != NULL) { FEvent *next = probe->Left; delete probe; probe = next; } } void FEventTree::DeleteAll () { DeletionTraverser (Root); Root = &Nil; } void FEventTree::DeletionTraverser (FEvent *node) { if (node != &Nil && node != NULL) { DeletionTraverser (node->Left); DeletionTraverser (node->Right); node->Left = Spare; Spare = node; } } FEvent *FEventTree::GetNewNode () { FEvent *node; if (Spare != NULL) { node = Spare; Spare = node->Left; } else { node = new FEvent; } return node; } void FEventTree::Insert (FEvent *z) { FEvent *y = &Nil; FEvent *x = Root; while (x != &Nil) { y = x; if (z->Distance < x->Distance) { x = x->Left; } else { x = x->Right; } } z->Parent = y; if (y == &Nil) { Root = z; } else if (z->Distance < y->Distance) { y->Left = z; } else { y->Right = z; } z->Left = &Nil; z->Right = &Nil; } FEvent *FEventTree::Successor (FEvent *event) const { if (event->Right != &Nil) { event = event->Right; while (event->Left != &Nil) { event = event->Left; } return event; } else { FEvent *y = event->Parent; while (y != &Nil && event == y->Right) { event = y; y = y->Parent; } return y; } } FEvent *FEventTree::Predecessor (FEvent *event) const { if (event->Left != &Nil) { event = event->Left; while (event->Right != &Nil) { event = event->Right; } return event; } else { FEvent *y = event->Parent; while (y != &Nil && event == y->Left) { event = y; y = y->Parent; } return y; } } FEvent *FEventTree::FindEvent (double key) const { FEvent *node = Root; while (node != &Nil) { if (node->Distance == key) { return node; } else if (node->Distance > key) { node = node->Left; } else { node = node->Right; } } return NULL; } FEvent *FEventTree::GetMinimum () { FEvent *node = Root; if (node == &Nil) { return NULL; } while (node->Left != &Nil) { node = node->Left; } return node; } void FEventTree::PrintTree (const FEvent *event) const { if (event->Left != &Nil) { PrintTree (event->Left); } printf (" Distance %g, vertex %d, seg %u\n", sqrt(event->Distance/4294967296.0), event->Info.Vertex, (unsigned)event->Info.FrontSeg); if (event->Right != &Nil) { PrintTree (event->Right); } }