binary_t.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 367 行 · 第 1/2 页
C
367 行
//
// Copyright (C) 1991 Texas Instruments Incorporated.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated provides this software "as is" without
// express or implied warranty.
//
#include <cool/Binary_Tree.h>
// CoolBinary_Tree -- Simple constructor to initialize a CoolBinary_Tree object
// Input: None
// Output: None
template <class Type>
CoolBinary_Tree<Type>::CoolBinary_Tree() {
this->compare = &default_node_compare; // Pointer to compare function
}
// CoolBinary_Tree -- constructor to initialize a CoolBinary_Tree object to have the
// same size and values as some other CoolBinary_Tree object
// Input: Reference to CoolBinary_Tree
// Output: None
template <class Type>
CoolBinary_Tree<Type>::CoolBinary_Tree(const CoolBinary_Tree<Type>& b)
{
this->compare = b.compare; // Pointer to compare function
this->number_nodes = b.number_nodes;
this->root = this->copy_nodes (b.get_root());
this->current_position () = b.current_position ();
}
// ~CoolBinary_Tree -- Destructor for the CoolBinary_Tree class
// Input: None
// Output: None
template <class Type>
CoolBinary_Tree<Type>::~CoolBinary_Tree() {
delete this->root; // Virtual destructor called recurs.
} // on all nodes
// value -- Return value of node at current position
// Input: None
// Output: Reference to value of node at current position
template <class Type>
Type& CoolBinary_Tree<Type>::value () {
#if ERROR_CHECKING
if (this->state.stack.is_empty() ) // If invalid current position
this->curpos_error (#Type, "value()"); // Raise exception
#endif
Stack_Entry stack_entry = this->state.stack.top(); // get top stack
return (((CoolBinary_Node<Type>*)stack_entry.get_first())->get()); // Return value
}
template <class Type>
Boolean CoolBinary_Tree<Type>::put_internal
(const Type& value, Boolean avl) {
if (this->root == NULL) { // If this is the first node
this->root = new CoolBinary_Node<Type> (value); // Add new node and value
this->number_nodes++; // Update node count
return TRUE; // Indicate success
}
CoolBinary_Node<Type>* ptr = (CoolBinary_Node<Type>*)this->root; // Start at root
BT_Stack stack; // Stack for AVL balancing
while (TRUE) { // Until we find location
int pos = (*this->compare)(ptr->get(),value); // Compare data values
if (pos == 0) // If data value exists in tree
return FALSE; // indicate node not added
else if (pos > 0) { // Data down left subtree?
if (avl)
stack.push (Stack_Entry (/*(CoolBinary_Node*)##*/ptr,LEFT)); // Push parent
if (ptr->get_ltree() == NULL) { // If at leaf node
ptr->set_ltree ((new CoolBinary_Node<Type> (value))); // Add node to ltree
this->number_nodes++; // Update node count
break; // Break out of loop and exit
}
else {
ptr = ptr->get_ltree(); // Else point to left subtree
continue; // And continue search
}
}
else { // Else down right subtree
if (avl)
stack.push (Stack_Entry (/*(CoolBinary_Node*)##*/ptr,RIGHT)); // Push on stack
if (ptr->get_rtree() == NULL) { // If at leaf node
ptr->set_rtree ((new CoolBinary_Node<Type> (value))); // Add node to rtree
this->number_nodes++; // Update node count
break; // Break out of loop and exit
}
else {
ptr = ptr->get_rtree(); // Grab right subtree dir
continue; // And continue to search;
}
}
}
if (avl) // Balance it if an AVL tree
CoolBase_Binary_Tree::avl_put_balance (stack);
this->reset(); // Invalidate current position
return TRUE; // Return success
}
// remove_internal -- does the actual work of removing a value from bin tree
// for avl trees, will make call to check avl balance
// Input: -- value to remove + optional Boolean for AVL trees
// output -- TRUE if item sucessfully removed. FALSE otherwise.
template <class Type>
Boolean CoolBinary_Tree<Type>::remove_internal
(const Type& value, Boolean avl) {
if (this->root == NULL) // If there are no nodes
return FALSE; // indicate failure
BT_Stack stack1; // Allocate traversal stack
Left_Right route = NONE; // Last subtree taken
CoolBinary_Node<Type> *ptr = (CoolBinary_Node<Type>*)this->root; // Start at root
CoolBinary_Node<Type> *parent_ptr = NULL; // Save pointer to parent
CoolBinary_Node<Type> *ptr1, *ptr2; // temp ptrs to nodes
while (TRUE) { // Until we find location
int pos = (*this->compare)(ptr->get(),value); // Compare data values
if (pos == 0) { // If node to delete is found
if (ptr->get_rtree() == NULL) { // If no right subtree
if (route == LEFT) // If child of parent's ltree
parent_ptr->set_ltree(ptr->get_ltree()); // Set to left subtree
else if (route == RIGHT)
parent_ptr->set_rtree(ptr->get_ltree()); // Set to right subtree
else this->root = ptr->get_ltree(); // Make ltree the new root
}
else if (ptr->get_ltree() == NULL) { // Else if no left subtree
if (route == LEFT) // If child of parent ltree
parent_ptr->set_ltree(ptr->get_rtree()); // Set to left subtree
else if (route == RIGHT)
parent_ptr->set_rtree(ptr->get_rtree()); // Set to right subtree
else this->root = ptr->get_rtree(); // rtree is the new root.
}
// Node(a) with value to be deleted has both a left and right subtree.
// We need to look for the node(b) with the next smallest value and
// copy it's value into node(a). Then adjust the parent of node(b)
// to point at node(b)'s left subtree (right subtree will always be
// NULL). ptr is left pointing at node(b) so it is the
// one which is eventually deleted.
else {
if (avl) // for avl trees
stack1.push (Stack_Entry(/*(CoolBinary_Node*)##*/ptr,LEFT)); // push on stack
ptr1 = ptr; // Save node with matched data
ptr2 = ptr1; // last parent initially ptr
ptr = ptr->get_ltree(); // Start with node's ltree
while (ptr->get_rtree() != NULL) { // Follow rtree til null rtree
if (avl) // for avl trees
stack1.push (Stack_Entry(/*(CoolBinary_Node*)##*/ptr,RIGHT)); // push on stack
ptr2 = ptr; // save last parent
ptr = ptr->get_rtree(); // get right subtree
}
ptr1->set (ptr->get()); // Move next smallest value up
if (ptr1 == ptr2) // ltree had no rtrees
ptr2->set_ltree (ptr->get_ltree()); // Del node is parents ltree
else
ptr2->set_rtree (ptr->get_ltree()); // Del node is parents rtree
}
// DELETE the node ptr points at
this->number_nodes--; // Decrement node count
if (this->number_nodes == 0) // If no more nodes in tree
this->root = NULL; // Nullify root pointer
ptr->set_ltree (NULL); // Nullify left subtree pointer
ptr->set_rtree (NULL); // Nullify right subtree pointer
delete ptr; // Deallocate memory
this->reset(); // Invalidate current position<
break; // exit loop
}
else if (pos > 0) { // Data down left subtree?
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?