create Red-Black tree head file, not tested yet.

This commit is contained in:
Shine wOng
2019-06-23 15:12:37 +08:00
parent b7742f2e7e
commit cf6af38144
5 changed files with 187 additions and 6 deletions

View File

@@ -6,6 +6,8 @@
#define BinNodePosi(T) BinNode<T>*
typedef enum{RED, BLACK} Color;
template <typename T>
class BinNode{
protected:
@@ -18,15 +20,14 @@ public:
BinNodePosi(T) parent;
BinNodePosi(T) leftChild;
BinNodePosi(T) rightChild;
Color color;
T data;
int height;
int color;
int npl;
//constructor
BinNode() : parent(nullptr), leftChild(nullptr), rightChild(nullptr), height(0), color(0), npl(0) {};
BinNode(T const &val) : parent(nullptr), leftChild(nullptr), rightChild(nullptr), data(val), height(0), color(0), npl(0) {};
BinNode(T const &val, BinNodePosi(T) p): parent(p), leftChild(nullptr), rightChild(nullptr), data(val), height(0), color(0), npl(0) {};
BinNode() : parent(nullptr), leftChild(nullptr), rightChild(nullptr), height(0), color(BLACK), npl(0) {};
BinNode(T const &val, BinNodePosi(T) p = nullptr, Color color = BLACK) : parent(p), leftChild(nullptr), rightChild(nullptr), data(val), height(0), color(color), npl(0) {};
int size() const; //compute the size of the tree rooted at current node
BinNodePosi(T) insertAsLC(T const &val); //always assume that this.leftChild == nullptr

View File

@@ -12,8 +12,8 @@ class BinTree{
protected:
BinNodePosi(T) __root;
int __size;
bool updateHeight(BinNodePosi(T) x);
void updateHeightAbove(BinNodePosi(T) x);
virtual bool updateHeight(BinNodePosi(T) x);
virtual void updateHeightAbove(BinNodePosi(T) x);
BinNodePosi(T) higherChild(BinNodePosi(T) x);
public:

View File

@@ -13,6 +13,7 @@ public:
V value;
//constructor
entry() = default;
entry(K k, V v) : key(k), value(v) {}
//overload operator

179
thu_dsa/chp8/RedBlack.h Normal file
View File

@@ -0,0 +1,179 @@
#ifndef REDBLACK_H_
#define REDBLACK_H_
#include "../chp7/BST.h"
#define ISBLACK(x) (!x || x->color == BLACK)
#define ISRED(x) (x && x->color == RED)
#define BLACK_HEIGHT(x) (x? x->height: 0)
#define BLACK_HEIGHT_CHANGED(x) (x && BLACK_HEIGHT(x->leftChild) != BLACK_HEIGHT(x->rightChild))
#define T entry<K, V>
template <typename K, typename V>
class RedBlack: public BST<K, V>{
protected:
BinNodePosi(T) zig(BinNodePosi(T) p); //right rotation
BinNodePosi(T) zag(BinNodePosi(T) p); //left rotation
void solveDoubleRed(BinNodePosi(T) x);
void solveDoubleBlack(BinNodePosi(T) x);
bool updateHeight(BinNodePosi(T) x);
public:
BinNodePosi(T) insert(K const &key, V const &value);
bool remove(K const &key);
};
// protected methods
template <typename K, typename V>
BinNodePosi(T) RedBlack<K, V>::zig(BinNodePosi(T) p){
BinNodePosi(T) x = p->leftChild;
p->leftChild = x->rightChild;
if (x->rightChild) x->rightChild->parent = p;
x->rightChild = p;
p->parent = x;
updateHeight(p);
updateHeight(x);
return x;
}
template <typename K, typename V>
BinNodePosi(T) RedBlack<K, V>::zag(BinNodePosi(T) p) {
BinNodePosi(T) x = p->rightChild;
p->rightChild = x->leftChild;
if (x->leftChild) x->leftChild->parent = p;
x->leftChild = p;
p->parent = x;
updateHeight(p);
updateHeight(x);
return x;
}
template <typename K, typename V>
bool RedBlack<K, V>::updateHeight(BinNodePosi(T) x){
if (!x) return false;
//else
int prevHeight = BLACK_HEIGHT(x);
if (ISBLACK(x->leftChild))
x->height = BLACK_HEIGHT(x->leftChild) + 1;
else x->height = BLACK_HEIGHT(x->leftChild);
return prevHeight != x->height;
}
template <typename K, typename V>
void RedBlack<K, V>::solveDoubleRed(BinNodePosi(T) x){
BinNodePosi(T) p = x->parent;
if (!p) { x->color = BLACK; return; } //x is __root
if (ISBLACK(p)) return;
//Double Red Exception
BinNodePosi(T) g = p->parent; //assert: g exists, for p is red
BinNodePosi(T) s = (p == g->leftChild ? g->rightChild : g->leftChild); //s is the uncle of x
//case 1: s is black
if (ISBLACK(s)) {
BinNodePosi(T) gg = g->parent;
BinNodePosi(T) newRoot = rotateAt(x);
if (gg)
(g == gg->leftChild ? gg->leftChild : gg->rightChild) = newRoot;
newRoot->color = BLACK;
newRoot->leftChild->color = RED;
newRoot->rightChild->color = RED;
updateHeight(newRoot->leftChild);
updateHeight(newRoot->rightChild);
updateHeight(newRoot);
return;
}
//case2: s is red
else {
g->color = RED;
s->color = BLACK;
p->color = BLACK;
updateHeight(g);
solveDoubleRed(g);
return;
}
}
template <typename K, typename V>
void RedBlack<K, V>::solveDoubleBlack(BinNodePosi(T) x){
BinNodePosi(T) p = (x ? x->parent : __hot);
BinNodePosi(T) s = (x == p->leftChild ? p->rightChild : p->leftChild);
//case one: s has at least one red child
if(ISRED(s->leftChild) || ISRED(s->rightChild)){
BinNodePosi(T) redChild = ISRED(s->leftChild) ? s->leftChild : s->rightChild;
BinNodePosi(T) g = p->parent;
BinNodePosi(T) newRoot = rotateAt(redChild);
if(g)
(p == g->leftChild? g->leftChild: g->rightChild) = newRoot:
redChild->color = BLACK;
updateHeight(newRoot->leftChild);
updateHeight(newRoot->rightChild);
updateHeight(newRoot);
return;
}
//case two: p is red
if(ISRED(p)){
p->color = BLACK;
s->color = RED;
updateHeight(p);
return;
}
//case three: p is black
if(ISBLACK(p)){
p->color = BLACK;
s->color = RED;
updateHeight(p);
solveDoubleBlack(p);
return;
}
//case four: s is red
if(ISRED(s)){
p->color = RED;
s->color = BLACK;
BinNodePosi(T) g = p->parent;
if(s == p->leftChild) zig(p);
else zag(p);
if (g) (p == g->leftChild ? g->leftChild : g->rightChild) = s;
solveDoubleBlack(x);
}
}
// public interfaces
template <typename K, typename V>
BinNodePosi(T) RedBlack<K, V>::insert(K const &key, V const &value){
BinNodePosi(T) &x = search(key);
if (x) return x;
//else
x = new BinNode<T>(entry<K, V>(key, value), __hot, RED);
x->height = 1; //external black height
++__size;
solveDoubleRed(x);
return x;
}
template <typename K, typename V>
bool RedBlack<K, V>::remove(K const &key){
BinNodePosi(T) &x = search(key);
if (!x) return false;
//else
BinNodePosi(T) succ = removeAt(x, __hot);
--__size;
if (ISRED(succ)) {
succ->color == BLACK;
return true;
}
if (!BLACK_HEIGHT_CHANGED(__hot)) return true;
solveDoubleBlack(succ);
return true;
}
#undef T
#endif

View File