// This is the file to include for access to the complete binary node // template implementation
#include"BinNode.h"
// Simple binary tree node implementation template <typename Key, typename E> classBSTNode : public BinNode<E> { private: Key k; // The node's key E it; // The node's value BSTNode* lc; // Pointer to left child BSTNode* rc; // Pointer to right child
public: // Two constructors -- with and without initial values BSTNode() { lc = rc = NULL; } BSTNode(Key K, E e, BSTNode* l =NULL, BSTNode* r =NULL) { k = K; it = e; lc = l; rc = r; } ~BSTNode() {} // Destructor
// Functions to set and return the value and key E& element(){ return it; } voidsetElement(const E& e){ it = e; } Key& key(){ return k; } voidsetKey(const Key& K){ k = K; }
// Functions to set and return the children inline BSTNode* left()const{ return lc; } voidsetLeft(BinNode<E>* b){ lc = (BSTNode*)b; } inline BSTNode* right()const{ return rc; } voidsetRight(BinNode<E>* b){ rc = (BSTNode*)b; }
// Return true if it is a leaf, false otherwise boolisLeaf(){ return (lc == NULL) && (rc == NULL); } };
// Test for variable nodes implemented with a composite design. // The test vehicle is an expression tree. // The program builds and traverses a simple tree.
#include"book.h"
typedefchar Operator; typedef string Operand;
// Node implementation with simple inheritance classVarBinNode { // Node abstract base class public: virtual ~VarBinNode() {} virtualboolisLeaf()= 0; // Subclasses must implement };
classLeafNode : public VarBinNode { // Leaf node private: Operand var; // Operand value
public: LeafNode(const Operand& val) { var = val; } // Constructor boolisLeaf(){ returntrue; } // Version for LeafNode Operand value(){ return var; } // Return node value };
classIntlNode : public VarBinNode { // Internal node private: VarBinNode* left; // Left child VarBinNode* right; // Right child Operator opx; // Operator value
public: IntlNode(const Operator& op, VarBinNode* l, VarBinNode* r) { opx = op; left = l; right = r; } // Constructor boolisLeaf(){ returnfalse; } // Version for IntlNode VarBinNode* leftchild(){ return left; } // Left child VarBinNode* rightchild(){ return right; } // Right child Operator value(){ return opx; } // Value };
voidtraverse(VarBinNode *root){ // Preorder traversal if (root == NULL) return; // Nothing to visit if (root->isLeaf()) // Do leaf node cout << "Leaf: " << ((LeafNode *)root)->value() << endl; else { // Do internal node cout << "Internal: " << ((IntlNode *)root)->value() << endl; traverse(((IntlNode *)root)->leftchild()); traverse(((IntlNode *)root)->rightchild()); } }
// Test for variable nodes implemented with a composite design. // The test vehicle is an expression tree. // The program builds and traverses a simple tree.
#include"book.h"
typedefchar Operator; typedef string Operand;
// Node implementation with the composite design pattern classVarBinNode { // Node abstract base class public: virtual ~VarBinNode() {} //Generic destructor virtualboolisLeaf()= 0; virtualvoidtraverse()= 0; };
classLeafNode : public VarBinNode { // Leaf node private: Operand var; // Operand value
// This file includes all of the pieces of the BST implementation
// Include the node implementation #include"BSTNode.h"
// Include the dictionary ADT #include"dictionary.h"
// Binary Search Tree implementation for the Dictionary ADT template <typename Key, typename E> classBST : public Dictionary<Key,E> { private: BSTNode<Key,E>* root; // Root of the BST int nodecount; // Number of nodes in the BST
// Insert a record into the tree. // k Key value of the record. // e The record to insert. voidinsert(const Key& k, const E& e){ root = inserthelp(root, k, e); nodecount++; }
// Remove a record from the tree. // k Key value of record to remove. // Return: The record removed, or NULL if there is none. E remove(const Key& k){ E temp = findhelp(root, k); // First find it if (temp != NULL) { root = removehelp(root, k); nodecount--; } return temp; } // Remove and return the root node from the dictionary. // Return: The record removed, null if tree is empty. E removeAny(){ // Delete min value if (root != NULL) { E temp = root->element(); root = removehelp(root, root->key()); nodecount--; return temp; } elsereturnNULL; }
// Return Record with key value k, NULL if none exist. // k: The key value to find. */ // Return some record matching "k". // Return true if such exists, false otherwise. If // multiple records match "k", return an arbitrary one. E find(const Key& k)const{ returnfindhelp(root, k); }
// Return the number of records in the dictionary. intsize(){ return nodecount; }
voidprint()const{ // Print the contents of the BST if (root == NULL) cout << "The BST is empty.\n"; elseprinthelp(root, 0); } };
// Insert a node into the BST, returning the updated tree template <typename Key, typename E> BSTNode<Key, E>* BST<Key, E>::inserthelp( BSTNode<Key, E>* root, const Key& k, const E& it) { if (root == NULL) // Empty tree: create node returnnewBSTNode<Key, E>(k, it, NULL, NULL); if (k < root->key()) root->setLeft(inserthelp(root->left(), k, it)); else root->setRight(inserthelp(root->right(), k, it)); return root; // Return tree with node inserted }
getmin函数:根据二叉检索树的特性,寻找最小值只需要沿着左边的链不断向下移直到无法再向下移。
1 2 3 4 5 6 7 8
// Get the minimum value from the BST, returning a pointer to the node template <typename Key, typename E> BSTNode<Key, E>* BST<Key, E>:: getmin(BSTNode<Key, E>* rt) { if (rt->left() == NULL) return rt; elsereturngetmin(rt->left()); }
// Delete the minimum value from the BST, returning the revised BST template <typename Key, typename E> BSTNode<Key, E>* BST<Key, E>:: deletemin(BSTNode<Key, E>* rt) { if (rt->left() == NULL) // Found min return rt->right(); else { // Continue left rt->setLeft(deletemin(rt->left())); return rt; } }
// Remove a node with key value k // Return: The tree with the node removed template <typename Key, typename E> BSTNode<Key, E>* BST<Key, E>:: removehelp(BSTNode<Key, E>* rt, const Key& k) { if (rt == NULL) returnNULL; // k is not in tree elseif (k < rt->key()) rt->setLeft(removehelp(rt->left(), k)); elseif (k > rt->key()) rt->setRight(removehelp(rt->right(), k)); else { // Found: remove it BSTNode<Key, E>* temp = rt; if (rt->left() == NULL) { // Only a right child rt = rt->right(); // so point to right delete temp; } elseif (rt->right() == NULL) { // Only a left child rt = rt->left(); // so point to left delete temp; } else { // Both children are non-empty BSTNode<Key, E>* temp = getmin(rt->right()); rt->setElement(temp->element()); rt->setKey(temp->key()); rt->setRight(deletemin(rt->right())); delete temp; } } return rt; }
findhelp函数:
1 2 3 4 5 6 7 8 9 10 11
// Find a node with the given key value template <typename Key, typename E> E BST<Key, E>::findhelp(BSTNode<Key, E>* root, const Key& k) const { if (root == NULL) returnNULL; // Empty tree if (k < root->key()) returnfindhelp(root->left(), k); // Check left elseif (k > root->key()) returnfindhelp(root->right(), k); // Check right elsereturn root->element(); // Found it }
printhelp函数:
1 2 3 4 5 6 7 8 9 10 11
// Print out a BST template <typename Key, typename E> void BST<Key, E>:: printhelp(BSTNode<Key, E>* root, int level) const { if (root == NULL) return; // Empty tree printhelp(root->left(), level+1); // Do left subtree for (int i=0; i<level; i++) // Indent to level cout << " "; cout << root->key() << "\n"; // Print node value printhelp(root->right(), level+1); // Do right subtree }