+ Rename output executables to match directory structure + Remove libraries for small examples + Supress -Wreturn-type warnings for singleton that is intentionally not copyable
		
			
				
	
	
		
			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
 |