template class Collection { protected: unsigned long count; public: Collection(): count(0) {} virtual void clear() = 0; virtual void add(const T &val) = 0; virtual const bool remove(const T &val) = 0; const unsigned long size() const {return count;} }; template class Node { public: T val; Node(const T &v): val(v) {} virtual ~Node() {} }; template class ListNode: public Node { public: ListNode *next, *prev; ListNode(const T &v): Node(v), next(0), prev(0) {} virtual ~ListNode() { if(next) next->prev = prev; if(prev) prev->next = next; } }; template class LinkedList: public Collection { protected: ListNode *head, *tail; public: class Iterator { friend class LinkedList; protected: ListNode *n; Iterator(ListNode *start): n(start) {} public: Iterator(const Iterator &other): n(other.n) {} virtual T &val() {return n->val;} virtual void next() {if(n) n = n->next;} virtual void prev() {if(n) n = n->prev;} virtual const bool has_val() {return (n ? true : false); } }; LinkedList(): Collection(), head(0), tail(0) {}; LinkedList(const LinkedList &other): Collection(), head(0), tail(0) { for(Iterator i = other.begin(); i.has_val(); i.next()) add(i.val()); } virtual ~LinkedList() { clear(); } LinkedList &operator=(const LinkedList &other) { clear(); for(Iterator i = other.begin(); i.has_val(); i.next()) add(i.val()); return *this; } virtual void clear() { ListNode *n; while(head) { n = head; head = head->next; delete n; } tail = 0; Collection::count = 0; } virtual Iterator begin() const {return Iterator(head);} virtual void add_front(T &val) { ListNode *n = new ListNode(val); n->next = head; if(head) head->prev = n; head = n; if(!tail) tail = n; Collection::count++; } virtual void add(const T &val) { ListNode *n = new ListNode(val); n->prev = tail; if(tail) tail->next = n; tail = n; if(!head) head = n; Collection::count++; } virtual const bool remove(const T &val) { ListNode *n = head; while(n) { if(n->val == val) { if(n == head) head = head->next; if(n == tail) tail = tail->prev; delete n; Collection::count--; return true; } else n = n->next; } return false; } virtual const bool contains(T &val) const { ListNode *n = head; while(n) { if(n->val == val) { return true; } else n = n->next; } return false; } // queue/stack functions // stack - use push/pop // queue - use push_back/pop virtual void push(T val) { add_front(val); } virtual void push_back(T &val) { add(val); } virtual const bool pop(T &val) { if(!head) return false; ListNode *n = head; if(head) { head = head->next; if(n == tail) tail = 0; val = n->val; delete n; Collection::count--; return true; } else return false; } }; template class DynamicArray: public Collection { protected: T *ar; unsigned long initial, limit, increment; public: class Iterator { friend class DynamicArray; protected: T *ar; unsigned long count; unsigned long pos; Iterator(T *a, const int c, unsigned long p): ar(a), count(c), pos(p) {} public: Iterator(const Iterator &other): ar(other.ar), count(other.count), pos(other.pos) {} virtual T &val() {return ar[pos];} virtual void next() {pos++;} virtual void prev() {pos--;} virtual const bool has_val() {return pos < count; } }; DynamicArray(unsigned long init = 0, unsigned long inc = 1): Collection(), ar(0), initial(init), limit(init), increment(inc) { if(limit) ar = (T *)malloc(limit * sizeof(T)); } virtual ~DynamicArray() {if(ar) free(ar);} virtual void clear() { Collection::count = 0; limit = initial; if(limit) ar = (T *)realloc(ar, limit * sizeof(T)); else { free(ar); ar = 0; } } virtual Iterator begin() const {return Iterator(ar, Collection::count, 0);} virtual void add(const T &val) { if(Collection::count == limit) { limit += increment; ar = (T *)realloc(ar, limit * sizeof(T)); ar[Collection::count++] = val; } else ar[Collection::count++] = val; } virtual void add_all(DynamicArray &other) { for(Iterator i = other.begin(); i != pl.end(); ++i) { add(i.val()); } } virtual const bool remove(const T &val) { for(unsigned long i = 0; i < Collection::count; i++) { if(ar[i] == val) { memmove(ar + i, ar + i + 1, (Collection::count - i) * sizeof(T)); Collection::count--; return true; } } return false; } virtual const bool remove(const unsigned long index) { if(index >= Collection::count) return false; memmove(ar + index, ar + index + 1, (Collection::count - index) * sizeof(T)); Collection::count--; return true; } virtual const bool insert(const T &val, const unsigned long index) { if(index > Collection::count) return false; if(Collection::count == limit) { limit += increment; ar = (T *)realloc(ar, limit * sizeof(T)); } if(index < Collection::count) memmove(ar + index + 1, ar + index, (Collection::count - index) * sizeof(T)); ar[index] = val; Collection::count++; return true; } virtual T &operator[](const int index) { return ar[index]; } const bool index_of(const T &val, unsigned long &index) const { for(int i = 0; i < Collection::count; i++) { if(ar[index] == val) { index = i; return true; } } return false; } const int index_of(const T &val) const { for(int i = 0; i < Collection::count; i++) { if(ar[i] == val) { return i; } } return -1; } // stack functions virtual const bool pop(T &val) { if(Collection::count) { val = ar[Collection::count -1]; remove(Collection::count -1); return true; } return false; } virtual void push(const T &val) { add(val); } }; template class SortedDynamicArray: public DynamicArray { public: SortedDynamicArray(unsigned long init = 0, unsigned long inc = 1): DynamicArray(init, inc) {} virtual ~SortedDynamicArray() {} const bool get_index(const T &val, unsigned long &index) { unsigned long low = 0; unsigned long high = Collection::count-1; while( high < Collection::count && low <= high ) { unsigned long i = ( low+high )/2; if ( DynamicArray::ar[i] == val ) { index = i; return true; } else if (DynamicArray::ar[i] < val) low = i+1; else high = i-1; } index = low; return false; } virtual void add(const T &val) { unsigned long index; get_index(val, index); insert(val, index); } }; template class TreeNode: public Node { public: TreeNode *parent, *left, *right; TreeNode(const T &v, TreeNode *par): Node(v), parent(par), left(0), right(0) {} virtual ~TreeNode() { if(parent) { if(parent->left == this) parent->left = 0; if(parent->right == this)parent->right = 0; } } }; template > class BinaryTree: public Collection { protected: N *root; virtual void delete_node(N *n) { if(n->left && n->right) { N *minmax = n->left; while(minmax->right) minmax = minmax->right; n->val = minmax->val; delete_node(minmax); return; } else if(n->right) { if(n->parent) { if(n->parent->left == n) n->parent->left = n->right; else n->parent->right = n->right; } else root = n->right; n->right->parent = n->parent; } else if(n->left) { if(n->parent) { if(n->parent->left == n) n->parent->left = n->left; else n->parent->right = n->left; } else root = n->left; n->left->parent = n->parent; } else { if(n == root) root = 0; } delete n; Collection::count--; } virtual void insert_node(N *n) { N *current = root, *parent = 0; while(current) { parent = current; if(n->val < current->val) current = current->left; else current = current->right; } if(parent) { if(n->val < parent->val) { parent->left = n; } else { parent->right = n; } } else root = n; n->parent = parent; Collection::count++; } public: class Iterator { friend class BinaryTree; protected: class EvalNode { public: bool evaluate; N *node; EvalNode(): evaluate(false), node(0) {} EvalNode(const bool eval, N *n): evaluate(eval), node(n) {} const bool operator==(const EvalNode &other) const {return node == other.node;} EvalNode &operator=(const EvalNode &other) {evaluate = other.evaluate; node = other.node; return *this;} }; N *n; LinkedList stack; Iterator(N *start): n(0) { if(start) { stack.push(EvalNode(true, start)); next(); } } public: Iterator(const Iterator &other):n(other.n), stack(other.stack) {} virtual ~Iterator() {} virtual T &val() {return n->val;} virtual void next() { EvalNode en; bool popped = false; while((popped = stack.pop(en)) && en.evaluate) { if(en.node->right) stack.push(EvalNode(true, en.node->right)); stack.push(EvalNode(false, en.node)); if(en.node->left) stack.push(EvalNode(true, en.node->left)); } n = (popped ? en.node : 0); } virtual const bool has_val() {return (n ? true : false);} }; BinaryTree(): Collection(), root(0) {}; BinaryTree(BinaryTree &other): Collection(), root(0) { for(Iterator i = other.begin(); i != pl.end(); ++i) add(i.val()); } virtual ~BinaryTree() {clear();} BinaryTree &operator=(BinaryTree &other) { clear(); for(Iterator i = other.begin(); i != pl.end(); ++i) add(i.val()); return *this; } virtual void clear() { N *current = root, *parent = 0; while(current) { if(current->left) current = current->left; else if(current->right) current = current->right; else { parent = current->parent; delete current; current = parent; } } root = 0; Collection::count = 0; } void add(const T &val) { N *n = new N(val, 0); insert_node(n); } const bool remove(const T &val) { N *current = root; while(current) { if(current->val == val) break; else if(val < current->val) current = current->left; else current = current->right; } if(current) { delete_node(current); return true; } return false; } const bool contains(const T &val) const { N *current = root; while(current) { if(current->val == val) break; else if(val < current->val) current = current->left; else current = current->right; } return current != 0; } Iterator begin() const {return Iterator(root);} }; #define RED 1 #define BLACK 0 // thanks to wikipedia (http://en.wikipedia.org/wiki/Red_black_tree) template class ColouredTreeNode: public Node { public: ColouredTreeNode *parent, *left, *right; char color; ColouredTreeNode(const T &v, ColouredTreeNode *par): Node(v), parent(par), left(0), right(0), color(BLACK) {} virtual ~ColouredTreeNode() { if(parent) { if(parent->left == this) parent->left = 0; if(parent->right == this)parent->right = 0; } } }; template > class RedBlackTree: public BinaryTree { protected: N *grandparent(N *n) { if (n && n->parent) return n->parent->parent; else return NULL; } N *uncle(N *n) { if(grandparent(n)) { if (n->parent == grandparent(n)->left) return grandparent(n)->right; else return grandparent(n)->left; } else return NULL; } N *sibling(N *n) { if(n->parent) { if (n == n->parent->left) return n->parent->right; else return n->parent->left; } else return NULL; } bool is_leaf(N *n) { return n == 0; } void replace_node(N *o, N *n) { n->parent = o->parent; if(n->parent) { if(n->parent->left == o) n->parent->left = n; else if(n->parent->right == o) n->parent->right = n; } else BinaryTree::root = n; } void rotate_left(N *n) { N *p = n->right; N *q = n; q->right = p->left; if(q->right) q->right->parent = q; p->left = q; p->parent = q->parent; q->parent = p; if(p->parent) { if(p->parent->left == q) p->parent->left = p; else if(p->parent->right == q) p->parent->right = p; } else BinaryTree::root = p; } void rotate_right(N *n) { N *p = n->left; N *q = n; q->left = p->right; if(q->left) q->left->parent = q; p->right = q; p->parent = q->parent; q->parent = p; if(p->parent) { if(p->parent->left == q) p->parent->left = p; else if(p->parent->right == q) p->parent->right = p; } else BinaryTree::root = p; } void insert_case1(N *n) { if (n->parent == NULL) n->color = BLACK; else insert_case2(n); } void insert_case2(N *n) { if (n->parent->color == BLACK) return; /* Tree is still valid */ else insert_case3(n); } void insert_case3(N *n) { if (uncle(n) != NULL && uncle(n)->color == RED) { n->parent->color = BLACK; uncle(n)->color = BLACK; grandparent(n)->color = RED; insert_case1(grandparent(n)); } else insert_case4(n); } void insert_case4(N *n) { if (n == n->parent->right && n->parent == grandparent(n)->left) { rotate_left(n->parent); n = n->left; } else if (n == n->parent->left && n->parent == grandparent(n)->right) { rotate_right(n->parent); n = n->right; } insert_case5(n); } void insert_case5(N *n) { n->parent->color = BLACK; grandparent(n)->color = RED; if (n == n->parent->left && n->parent == grandparent(n)->left) { rotate_right(grandparent(n)); } else { /* Here, n == n->parent->right && n->parent == grandparent(n)->right */ rotate_left(grandparent(n)); } } void delete_case0(N *n) { /* Precondition: n has at most one non-null child */ N *child = is_leaf(n->right) ? n->left : n->right; if(child) replace_node(n, child); if (n->color == BLACK) { if(child) { if (child->color == RED) child->color = BLACK; else delete_case1(child); } else delete_case1(n); } if(BinaryTree::root == n) BinaryTree::root = 0; delete n; Collection::count--; } void delete_case1(N *n) { if (n->parent == NULL) return; else delete_case2(n); } void delete_case2(N *n) { if (sibling(n) && sibling(n)->color == RED) { n->parent->color = RED; sibling(n)->color = BLACK; if (n == n->parent->left) rotate_left(n->parent); else rotate_right(n->parent); } delete_case3(n); } void delete_case3(N *n) { if (n->parent->color == BLACK && sibling(n) && sibling(n)->color == BLACK && (sibling(n)->left == 0 || sibling(n)->left->color == BLACK) && (sibling(n)->right == 0 || sibling(n)->right->color == BLACK)) { sibling(n)->color = RED; delete_case1(n->parent); } else delete_case4(n); } void delete_case4(N *n) { if (n->parent->color == RED && sibling(n) && sibling(n)->color == BLACK && (sibling(n)->left == 0 || sibling(n)->left->color == BLACK) && (sibling(n)->right == 0 || sibling(n)->right->color == BLACK)) { sibling(n)->color = RED; n->parent->color = BLACK; } else delete_case5(n); } void delete_case5(N *n) { if (n == n->parent->left && sibling(n) && sibling(n)->color == BLACK && sibling(n)->left && sibling(n)->left->color == RED && (sibling(n)->right == 0 || sibling(n)->right->color == BLACK)) { sibling(n)->color = RED; sibling(n)->left->color = BLACK; rotate_right(sibling(n)); } else if (n == n->parent->right && sibling(n) && sibling(n)->color == BLACK && sibling(n)->right && sibling(n)->right->color == RED && (sibling(n)->left == 0 || sibling(n)->left->color == BLACK)) { sibling(n)->color = RED; sibling(n)->right->color = BLACK; rotate_left(sibling(n)); } delete_case6(n); } void delete_case6(N *n) { sibling(n)->color = n->parent->color; n->parent->color = BLACK; if (n == n->parent->left) { /* Here, sibling(n)->right->color == RED */ sibling(n)->right->color = BLACK; rotate_left(n->parent); } else { /* Here, sibling(n)->left->color == RED */ sibling(n)->left->color = BLACK; rotate_right(n->parent); } } N *get_predecessor(N *n) { N *minmax = n->left; while(minmax->right) minmax = minmax->right; return minmax; } virtual void insert_node(N *n) { BinaryTree::insert_node(n); n->color = RED; insert_case1(n); } virtual void delete_node(N *n) { if(n->left && n->right) { N *predecessor = get_predecessor(n); n->val = predecessor->val; delete_case0(predecessor); } else delete_case0(n); } public: RedBlackTree(): BinaryTree< T, N >() {} virtual ~RedBlackTree() {} }; template class Pair { public: A first; B second; Pair(const A &f): first(f) {} Pair(const A &f, const B &s): first(f), second(s) {} Pair(const Pair &other): first(other.first), second(other.second) {} virtual ~Pair() {} const bool operator<(const Pair &other) const {return first < other.first;} const bool operator==(const Pair &other) const {return first == other.first;} Pair &operator=(const Pair &other) {first = other.first; second = other.second; return *this;} }; //template > > class Map: public BinaryTree< Pair< A, B >, N > { template > > class Map: public RedBlackTree< Pair< A, B >, N > { protected: N *find(A &key) const { N *n = RedBlackTree< Pair< A, B >, N >::root; while(n) { if(n->val.first == key) return n; else if(key < n->val.first) n = n->left; else n = n->right; } return 0; } public: //Map(): BinaryTree< Pair, N >() {} Map(): RedBlackTree< Pair, N >() {} virtual ~Map() {} void put(A &key, B &value) { add(Pair(key, value)); } const bool get(A &key, B &val) const { const N *n = find(key); if(n) { val = n->val.second; return true; } else return false; } B &operator[](A &key) { N *n = find(key); if(n) return n->val.second; else { Pair< A, B > p(key); N *n = new N(p, 0); insert_node(n); return n->val.second; } } virtual const bool exists(A &key) const { const N *n = find(key); if(n) { return true; } else return false; } virtual const bool remove(A &key) { N *n = find(key); if(n) { delete_node(n); return true; } else return false; } };