101 lines
3.8 KiB
C++
101 lines
3.8 KiB
C++
/*#############################################################################
|
|
## Author: Shaun Reed ##
|
|
## Legal: All Content (c) 2022 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>
|
|
|
|
enum Color {Black, Red};
|
|
|
|
class RedBlackTree {
|
|
|
|
public:
|
|
// RedBlackNode Structure
|
|
struct RedBlackNode{
|
|
int element;
|
|
Color color = Black;
|
|
RedBlackNode *left{}, *right{}, *parent{};
|
|
|
|
RedBlackNode() : element(INT32_MIN), color(Black) {}
|
|
// Ctor for specific element, lhs, rhs
|
|
RedBlackNode(const int &el, Color c,
|
|
RedBlackNode *lt, RedBlackNode *rt, RedBlackNode *p)
|
|
:element(el), color(c), left(lt), right(rt), parent(p) {};
|
|
// Ctor for copying a node and any downstream nodes
|
|
RedBlackNode(const RedBlackNode &toCopy);
|
|
};
|
|
static RedBlackNode *nil;
|
|
|
|
RedBlackTree() : root(nil) {};
|
|
RedBlackTree(const RedBlackTree &rhs);;
|
|
RedBlackTree& operator=(RedBlackTree rhs);
|
|
~RedBlackTree() { makeEmpty(root);};
|
|
// Inlined functions provide less verbose interface for using the RBT
|
|
inline RedBlackNode * getRoot() const { return root;}
|
|
|
|
void rotateLeft(RedBlackNode *pivotNode);
|
|
void rotateRight(RedBlackNode *pivotNode);
|
|
void insertFixup(RedBlackNode * start);
|
|
void deleteFixup(RedBlackNode * start);
|
|
|
|
// 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, RedBlackNode *start) const;
|
|
|
|
// Empties a given tree or subtree
|
|
inline void makeEmpty() { makeEmpty(root);}
|
|
void makeEmpty(RedBlackNode *&tree);
|
|
// Checks if this RBT is empty
|
|
bool isEmpty() const;
|
|
|
|
// Insert and remove values from a tree or subtree
|
|
inline void insert(const int &x) { insert(x, root, nil);}
|
|
void insert(const int &newValue, RedBlackNode *&start, RedBlackNode *prevNode);
|
|
inline void remove(const int &x) { remove(search(x, root));}
|
|
void remove(RedBlackNode *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(RedBlackNode *start) const;
|
|
void printPostOrder(RedBlackNode *start) const;
|
|
void printPreOrder(RedBlackNode *start) const;
|
|
|
|
// Find a BinaryNode containing value starting at a given tree / subtree node
|
|
inline RedBlackNode * search(const int &value) const
|
|
{ return search(value, root);}
|
|
RedBlackNode * search(const int &value, RedBlackNode *start) const;
|
|
|
|
inline RedBlackNode * findMin() const { return findMin(root);}
|
|
inline RedBlackNode * findMax() const { return findMax(root);}
|
|
// Find nodes with min / max values starting at a given tree / subtree node
|
|
RedBlackNode * findMin(RedBlackNode *start) const;
|
|
RedBlackNode * findMax(RedBlackNode *start) const;
|
|
|
|
inline RedBlackNode * predecessor(const int &value) const
|
|
{ return predecessor(search(value));}
|
|
RedBlackNode * predecessor(RedBlackNode *startNode) const;
|
|
inline RedBlackNode * successor(const int &value) const
|
|
{ return successor(search(value));}
|
|
RedBlackNode * successor(RedBlackNode *startNode) const;
|
|
|
|
private:
|
|
RedBlackNode * clone(RedBlackNode *start);
|
|
void transplant(RedBlackNode *oldNode, RedBlackNode *newNode);
|
|
|
|
// The root node for the RBT
|
|
RedBlackNode *root;
|
|
};
|
|
|
|
#endif // REDBLACK_H
|