84 lines
3.3 KiB
C
84 lines
3.3 KiB
C
|
/*#############################################################################
|
||
|
## Author: Shaun Reed ##
|
||
|
## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ##
|
||
|
## About: An example of a red black tree implementation ##
|
||
|
## The algorithms in this example are seen in MIT Intro to Algorithms ##
|
||
|
## ##
|
||
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||
|
##############################################################################
|
||
|
*/
|
||
|
|
||
|
#ifndef REDBLACK_H
|
||
|
#define REDBLACK_H
|
||
|
|
||
|
#include <iostream>
|
||
|
|
||
|
// TODO: Add balance() method to balance overweight branches
|
||
|
class BinarySearchTree {
|
||
|
|
||
|
public:
|
||
|
// BinaryNode Structure
|
||
|
struct BinaryNode{
|
||
|
int element;
|
||
|
BinaryNode *left, *right, *parent;
|
||
|
|
||
|
// Ctor for specific element, lhs, rhs
|
||
|
BinaryNode(const int &el, BinaryNode *lt, BinaryNode *rt, BinaryNode *p)
|
||
|
:element(el), left(lt), right(rt), parent(p) {};
|
||
|
// Ctor for a node and any downstream nodes
|
||
|
explicit BinaryNode(BinaryNode * toCopy);
|
||
|
};
|
||
|
|
||
|
BinarySearchTree() : root(nullptr) {};
|
||
|
BinarySearchTree(const BinarySearchTree &rhs) : root(rhs.clone(rhs.root)) {};
|
||
|
BinarySearchTree& operator=(const BinarySearchTree& rhs);
|
||
|
~BinarySearchTree() { makeEmpty(root);};
|
||
|
inline BinaryNode * getRoot() const { return root;}
|
||
|
|
||
|
// Check if value is within the tree or subtree
|
||
|
inline bool contains(const int &value) const { return contains(value, root);}
|
||
|
bool contains(const int &value, BinaryNode *start) const;
|
||
|
|
||
|
// Empties a given tree or subtree
|
||
|
inline void makeEmpty() { makeEmpty(root);}
|
||
|
void makeEmpty(BinaryNode *&tree);
|
||
|
// Checks if this BST is empty
|
||
|
bool isEmpty() const;
|
||
|
|
||
|
// Insert and remove values from a tree or subtree
|
||
|
inline void insert(const int &x) { insert(x, root, nullptr);}
|
||
|
void insert(const int &newValue, BinaryNode *&start, BinaryNode *prevNode);
|
||
|
inline void remove(const int &x) { remove(search(x, root));}
|
||
|
void remove(BinaryNode *removeNode);
|
||
|
|
||
|
// Traversal functions
|
||
|
inline void printInOrder() const { printInOrder(root);}
|
||
|
inline void printPostOrder() const { printPostOrder(root);}
|
||
|
inline void printPreOrder() const { printPreOrder(root);}
|
||
|
// Overloaded to specify traversal of a subtree
|
||
|
void printInOrder(BinaryNode *start) const;
|
||
|
void printPostOrder(BinaryNode *start) const;
|
||
|
void printPreOrder(BinaryNode *start) const;
|
||
|
|
||
|
// Find a BinaryNode containing value starting at a given tree / subtree node
|
||
|
inline BinaryNode * search(const int &value) const { return search(value, root);}
|
||
|
BinaryNode * search(const int &value, BinaryNode *start) const;
|
||
|
inline BinaryNode * findMin() const { return findMin(root);}
|
||
|
inline BinaryNode * findMax() const { return findMax(root);}
|
||
|
// Find nodes with min / max values starting at a given tree / subtree node
|
||
|
BinaryNode * findMin(BinaryNode *start) const;
|
||
|
BinaryNode * findMax(BinaryNode *start) const;
|
||
|
|
||
|
BinaryNode * predecessor(BinaryNode *startNode) const;
|
||
|
BinaryNode * successor(BinaryNode *startNode) const;
|
||
|
|
||
|
private:
|
||
|
// BST Private Member Functions
|
||
|
static BinaryNode * clone(BinaryNode *start);
|
||
|
void transplant(BinaryNode *oldNode, BinaryNode *newNode);
|
||
|
|
||
|
BinaryNode *root;
|
||
|
};
|
||
|
|
||
|
#endif // REDBLACK_H
|