///////////////////////////////////////////////////////////////////// // // LLIST.H // // class Node; | _prev, _next // template class ListNode : public Node; | _val // template class List; | header, win, _length // template class Stack | push, pop // template class TreeNode; | _lchild, _rchild, val // template class BraidedNode : public Node, public TreeNode; // template class RandomizedNode : public BraidedNode; | _parent,_priority // template class SearchTree; | root, fnCmp // template class BraidedSearchTree | root, win, fnCmp // template class RandomizedSearchTree; | root, win, fnCmp // template List *arrayToList(T a[], int n); // template T leastItem(List &s, int (*cmp)(T,T) ); // // RomaNets Text Windows Library (RTWL) // // version 0.60 // // Michael J.Laszlo // Sergey RomaNets // // ------------------------------------------------------------------- // added length() to RandomizedSearchTree // added empty() to List // ------------------------------------------------------------------- #ifndef _LLIST_H_ #define _LLIST_H_ #define Dictionary RandomizedSearchTree //* typedef int bool; #define true 1 #define false 0 //*/ //////////////////////////////////////////////////////////// class Node { protected: Node* _next; Node* _prev; public: Node(void); virtual ~Node(void); Node* next(void); Node* prev(void); Node* insert(Node*); Node* remove(void); void splice(Node*); }; //////////////////////////////////////////////////////////// template class ListNode : public Node { public: T _val; ListNode( T val); friend class List; }; //////////////////////////////////////////////////////////// template class List { private: ListNode *header; ListNode *win; int _length; public: List (void); ~List (void); T insert(T); T append(T); List* append(List* l); T prepend(T); T remove(void); void empty(void); void val(T); T val(void); T next(void); T prev(void); T first(void); T last(void); int length(void); bool isFirst(void); bool isLast(void); bool isHead(void); }; //////////////////////////////////////////////////////////// template class Stack { private: List *s; public: Stack(void); ~Stack(void); void push(T v); T pop(void); bool empty(void); int size(void); T top(void); T nextToTop(void); T bottom(void); }; //////////////////////////////////////////////////////////// template class TreeNode { protected: TreeNode *_lchild; TreeNode *_rchild; T val; public: TreeNode(T); virtual ~TreeNode(void); friend class SearchTree; friend class BraidedSearchTree; }; //////////////////////////////////////////////////////////// template class SearchTree { private: TreeNode *root; int (*cmp)(T,T); TreeNode* _findMin( TreeNode *); void _remove(T, TreeNode * &); void _inorder(TreeNode*, void (*)(T)); public: SearchTree(int(*c)(T,T)); ~SearchTree(void); int isEmpty(void); T find(T); T findMin(void); void inorder(void(*visit)(T)); void insert(T); void remove(T); T removeMin(void); }; ///////////////////////////////////////////////////////////////////// template class BraidedNode : public Node, public TreeNode { public: BraidedNode (T); BraidedNode *rchild(void); BraidedNode *lchild(void); BraidedNode *next(void); BraidedNode *prev(void); friend class BraidedSearchTree; }; ///////////////////////////////////////////////////////////////////// template class BraidedSearchTree { private: BraidedNode *root; BraidedNode *win; int (*cmp) (T,T); void _remove( T, TreeNode* &); public: BraidedSearchTree(int(*) (T,T)); ~BraidedSearchTree(void); T next(void); T prev(void); void inorder(void(*) (T)); T val(void); bool isFirst(void); bool isLast(void); bool isHead(void); bool isEmpty(void); T find(T); T findMin(void); T insert(T); void remove(void); T removeMin(void); }; //////////////////////////////////////////////////////////// template class RandomizedNode : public BraidedNode { protected: RandomizedNode *_parent; double _priority; void rotateRight(void); void rotateLeft(void); void bubbleUp(void); void bubbleDown(void); public: RandomizedNode( T v, int seed = -1); RandomizedNode *lchild(void); RandomizedNode *rchild(void); RandomizedNode *next(void); RandomizedNode *prev(void); RandomizedNode *parent(void); double priority(void); friend class RandomizedSearchTree; }; //////////////////////////////////////////////////////////// template class RandomizedSearchTree { private: RandomizedNode *root; RandomizedNode *win; int _length; int (*cmp)(T,T); void _remove(RandomizedNode*); public: RandomizedSearchTree(int(*)(T,T), int = -1); ~RandomizedSearchTree(void); T next(void); T prev(void); void inorder(void(*)(T)); T val (void); bool isFirst(void); bool isLast(void); bool isHead(void); bool isEmpty(void); T find(T); T findMin(void); T locate(T); T insert(T); void remove(void); T remove(T); T removeMin(void); int length(void) { return _length;} }; // ......................................................... template ListNode::ListNode(T val) : _val(val) { } // ......................................................... template List::List(void) { _length = 0; header = new ListNode (NULL); win = header; } // ......................................................... template List::~List(void) { last(); while (length()) remove(); delete header; } // ......................................................... template void List::empty(void) { last(); while (length()) delete remove(); } // ......................................................... template T List::insert(T val) { win->insert( new ListNode(val)); ++_length; return val; } // ......................................................... template T List::prepend(T val) { header->insert( new ListNode(val)); ++_length; return val; } // ......................................................... template T List::append(T val) { header->prev()->insert( new ListNode(val)); ++_length; return val; } // ......................................................... template List* List::append(List *l) { ListNode *a = (ListNode*)header->prev(); a->splice(l->header); _length += l->_length; l->header->remove(); l->_length = 0; l->win = header; return this; } // ......................................................... template T List::remove(void) { if (win == header) return NULL; T val = win->_val; win = (ListNode*)win->prev(); delete (ListNode*)win->next()->remove(); --_length; return val; } // ......................................................... template void List::val(T v) { if (win != header) win->_val = v; } // ......................................................... template T List::val(void) { return win->_val; } // ......................................................... template T List::next(void) { win = (ListNode*) win->next(); return win->_val; } // ......................................................... template T List::prev(void) { win = (ListNode*) win->prev(); return win->_val; } // ......................................................... template T List::first(void) { win = (ListNode*) header->next(); return win->_val; } // ......................................................... template T List::last(void) { win = (ListNode*) header->prev(); return win->_val; } // ......................................................... template int List::length(void) { return _length; } // ......................................................... template bool List::isFirst(void) { return ( (win == header->next() ) && (_length > 0) ); } // ......................................................... template bool List::isLast(void) { return ( (win == header->prev() ) && (_length > 0) ); } // ......................................................... template bool List::isHead(void) { return ( win == header); } // ......................................................... template Stack::Stack(void) : s(new List) { } // ......................................................... template Stack::~Stack(void) { delete s; } // ......................................................... template void Stack::push( T v) { s->prepend(v); } // ......................................................... template T Stack::pop( void) { s->first(); return s->remove(); } // ......................................................... template bool Stack::empty( void) { return (s->length() == 0); } // ......................................................... template int Stack::size( void) { return s->length(); } // ......................................................... template T Stack::top( void) { return s->first(); } // ......................................................... template T Stack::nextToTop( void) { s->first(); return s->next(); } // ......................................................... template T Stack::bottom( void) { return s->last(); } // ......................................................... template TreeNode::TreeNode(T v) : val(v), _lchild(NULL), _rchild(NULL) { } // ......................................................... template TreeNode::~TreeNode(void) { if (_lchild) delete _lchild; if (_rchild) delete _rchild; } // ......................................................... template SearchTree::SearchTree(int(*c)(T,T) ) : cmp(c), root(NULL) { } // ......................................................... template int SearchTree::isEmpty(void) { return (root == NULL); } // ......................................................... template SearchTree::~SearchTree(void) { if (root) delete root; } // ......................................................... template T SearchTree::find(T val) { TreeNode *n= root; while (n) { int result = (*cmp)(val, n->val); if (result < 0) n = n->_lchild; else if ( result > 0) n = n->_rchild; else return n->val; } return NULL; } // ......................................................... template T SearchTree::findMin(void) { TreeNode *n = _findMin(root); return (n ? n->val : NULL); } // ......................................................... template TreeNode *SearchTree::_findMin(TreeNode *n) { if ( n == NULL) return NULL; while ( n->_lchild) n = n->_lchild; return n; } // ......................................................... template void SearchTree::inorder(void(*visit) (T)) { _inorder (root, visit); } // ............................................................................ template void SearchTree::_inorder(TreeNode *n, void(*visit)(T)) { if (n) { _inorder(n->_lchild, visit); (*visit)(n->val); _inorder(n->_rchild, visit); } } // ......................................................... template void SearchTree::insert(T val) { if (root == NULL) { root = new TreeNode(val); return; } else { int result; TreeNode *p, *n = root; while (n) { p = n; result = (*cmp)(val,p->val); if ( result < 0 ) n = p->_lchild; else if ( result > 0 ) n = p->_rchild; else return; } if (result < 0) p->_lchild = new TreeNode(val); else p->_rchild = new TreeNode(val); } } // ......................................................... template void SearchTree::remove(T val) { _remove(val, root); } // ............................................................................ template void SearchTree::_remove( T val, TreeNode * &n) { if ( n== NULL) return; int result = (*cmp)(val, n->val); if ( result < 0) _remove( val, n->_lchild); else if ( result > 0) _remove( val, n->_rchild); else { if (n->_lchild == NULL) { TreeNode *old = n; n = old->_rchild; //delete old; // don't work return; } else if (n->_rchild == NULL) { TreeNode *old = n; n = old->_lchild; //delete old; return; } else { TreeNode *m = _findMin(n->_rchild); n->val = m->val; _remove(m->val, n->_rchild); } } } // ......................................................... template T SearchTree::removeMin(void) { T v = findMin(); remove(v); return v; } // ......................................................... template BraidedNode::BraidedNode( T val) : TreeNode(val) { } // ......................................................... template BraidedNode *BraidedNode::rchild(void) { return (BraidedNode *) _rchild; } // ......................................................... template BraidedNode *BraidedNode::lchild(void) { return (BraidedNode *) _lchild; } // ......................................................... template BraidedNode *BraidedNode::next(void) { return (BraidedNode *) _next; } // ......................................................... template BraidedNode *BraidedNode::prev(void) { return (BraidedNode *) _prev; } // ......................................................... template BraidedSearchTree::BraidedSearchTree( int(*c) (T,T)) : cmp(c) { win = root = new BraidedNode(NULL); } // ......................................................... template BraidedSearchTree::~BraidedSearchTree(void) { delete root; } // ......................................................... template T BraidedSearchTree::next(void) { win = win->next(); return win->val; } // ......................................................... template T BraidedSearchTree::prev(void) { win = win->prev(); return win->val; } // ......................................................... template T BraidedSearchTree::val(void) { return win->val; } // ......................................................... template void BraidedSearchTree::inorder(void (*visit) (T)) { BraidedNode *n = root->next(); while ( n != root) { (*visit)(n->val); n = n->next(); } } // ......................................................... template bool BraidedSearchTree::isFirst(void) { return (win == root->next() ) && (root != root->next() ); } // ......................................................... template bool BraidedSearchTree::isLast(void) { return (win == root->prev() ) && (root != root->next() ); } // ......................................................... template bool BraidedSearchTree::isHead(void) { return (win == root); } // ......................................................... template bool BraidedSearchTree::isEmpty(void) { return (win == root->next()); } // ......................................................... template T BraidedSearchTree::find(T val) { BraidedNode *n= root->rchild(); while (n) { int result = (*cmp)(val, n->val); if (result < 0) n = n->lchild(); else if ( result > 0) n = n->rchild(); else { win = n; return n->val; } } return NULL; } // ......................................................... template T BraidedSearchTree::findMin(void) { win = root->next(); return win->val; } // ......................................................... template T BraidedSearchTree::insert(T val) { int result = 1; BraidedNode *p = root; BraidedNode *n = root->rchild(); while (n) { p = n; result = (*cmp)(val,p->val); if ( result < 0 ) n = p->lchild(); else if ( result > 0 ) n = p->rchild(); else return NULL; } win = new BraidedNode(val); if ( result < 0) { p->_lchild = win; p->prev()->Node::insert(win); } else { p->_rchild = win; p->Node::insert(win); } return val; } // ......................................................... template void BraidedSearchTree::remove(void) { if ( win != root) _remove(win->val, root->_rchild); } // ............................................................................ template void BraidedSearchTree::_remove( T val, TreeNode * &n) { int result = (*cmp)(val, n->val); if ( result < 0) _remove( val, n->_lchild); else if ( result > 0) _remove( val, n->_rchild); else { if (n->_lchild == NULL) { BraidedNode *old = (BraidedNode*)n; if ( win == old) win = old->prev(); n = old->rchild(); old->Node::remove(); //delete old; return; } else if (n->_rchild == NULL) { BraidedNode *old = (BraidedNode*)n; if ( win == old) win = old->prev(); n = old->lchild(); old->Node::remove(); //delete old; return; } else { BraidedNode *m = ( (BraidedNode*)n)->next(); n->val = m->val; _remove(m->val, n->_rchild); } } } // ......................................................... template T BraidedSearchTree::removeMin(void) { T val = root->next()->val; if (root != root->next() ) _remove(val, root->_rchild); return val; } // ......................................................... template RandomizedNode::RandomizedNode( T v, int seed) : BraidedNode(v) { if ( seed != -1) srand(seed); _priority = (rand()%32767)/32767.0; _parent = NULL; } // ......................................................... template void RandomizedNode::rotateRight(void) { RandomizedNode *y = this; RandomizedNode *x = y->lchild(); RandomizedNode *p = y->parent(); y->_lchild = x->rchild(); if ( y->lchild() != NULL) y->lchild()->_parent = y; if ( p->rchild() == y) p->_rchild = x; else p->_lchild = x; x->_parent = p; x->_rchild = y; y->_parent = x; } // ......................................................... template void RandomizedNode::rotateLeft(void) { RandomizedNode *x = this; RandomizedNode *y = x->rchild(); RandomizedNode *p = x->parent(); x->_rchild = y->lchild(); if ( x->rchild() != NULL) x->rchild()->_parent = x; if ( p->lchild() == x) p->_lchild = y; else p->_rchild = y; y->_parent = p; y->_lchild = x; x->_parent = y; } // ......................................................... template void RandomizedNode::bubbleUp(void) { RandomizedNode *p = parent(); if (priority() < p->priority() ) { if (p->lchild() == this) p->rotateRight(); else p->rotateLeft(); bubbleUp(); } } // ......................................................... template void RandomizedNode::bubbleDown(void) { double lcPriority = lchild() ? lchild()->priority() : 2.0; double rcPriority = rchild() ? rchild()->priority() : 2.0; double minPriority = (lcPriority < rcPriority) ? lcPriority : rcPriority; if ( priority() <= minPriority) return; if ( lcPriority < rcPriority) rotateRight(); else rotateLeft(); bubbleDown(); } // ......................................................... template RandomizedNode *RandomizedNode::rchild(void) { return (RandomizedNode*) _rchild; } // ......................................................... template RandomizedNode *RandomizedNode::lchild(void) { return (RandomizedNode*) _lchild; } // ......................................................... template RandomizedNode *RandomizedNode::next(void) { return (RandomizedNode*) _next; } // ......................................................... template RandomizedNode *RandomizedNode::prev(void) { return (RandomizedNode*) _prev; } // ......................................................... template RandomizedNode *RandomizedNode::parent(void) { return (RandomizedNode*) _parent; } // ......................................................... template double RandomizedNode::priority(void) { return _priority; } // ......................................................... template RandomizedSearchTree::RandomizedSearchTree(int (*c)(T,T),int seed) : cmp(c) { win = root = new RandomizedNode (NULL,seed); root->_priority = -1.0; _length = 0; } // ......................................................... template RandomizedSearchTree::~RandomizedSearchTree(void) { delete root; } // ......................................................... template T RandomizedSearchTree::next(void) { win = win->next(); return win->val; } // ......................................................... template T RandomizedSearchTree::prev(void) { win = win->prev(); return win->val; } // ......................................................... template T RandomizedSearchTree::val(void) { return win->val; } // ......................................................... template void RandomizedSearchTree::inorder(void (*visit) (T)) { RandomizedNode *n = root->next(); while ( n != root) { (*visit)(n->val); n = n->next(); } } // ......................................................... template bool RandomizedSearchTree::isFirst(void) { return (win == root->next() ) && (root != root->next() ); } // ......................................................... template bool RandomizedSearchTree::isLast(void) { return (win == root->prev() ) && (root != root->next() ); } // ......................................................... template bool RandomizedSearchTree::isHead(void) { return (win == root); } // ......................................................... template bool RandomizedSearchTree::isEmpty(void) { return (root == root->next()); } // ......................................................... template T RandomizedSearchTree::find(T val) { RandomizedNode *n= root->rchild(); while (n) { int result = (*cmp)(val, n->val); if (result < 0) n = n->lchild(); else if ( result > 0) n = n->rchild(); else { win = n; return n->val; } } return NULL; } // ......................................................... template T RandomizedSearchTree::findMin(void) { win = root->next(); return win->val; } // ......................................................... template T RandomizedSearchTree::locate(T val) { RandomizedNode *b = root; RandomizedNode *n = root->rchild(); while (n) { int result = (*cmp)(val, n->val); if ( result < 0) n = n->lchild(); else if ( result > 0) { b = n; n = n->rchild(); } else { win = n; return win->val; } } win = b; return win->val; } // ......................................................... template T RandomizedSearchTree::insert(T val) { int result = 1; RandomizedNode *p = root; RandomizedNode *n = root->rchild(); while (n) { p = n; result = (*cmp)(val,p->val); if ( result < 0 ) n = p->lchild(); else if ( result > 0 ) n = p->rchild(); else return NULL; } win = new RandomizedNode(val); win->_parent = p; if ( result < 0) { p->_lchild = win; p->prev()->Node::insert(win); } else { p->_rchild = win; p->Node::insert(win); } win->bubbleUp(); ++_length; return val; } // ......................................................... template void RandomizedSearchTree::remove(void) { if ( win != root) _remove(win); } // ......................................................... template T RandomizedSearchTree::removeMin(void) { T val = root->next()->val; if (root != root->next() ) _remove( root->next()); return val; } // ......................................................... template void RandomizedSearchTree::_remove(RandomizedNode *n) { n->_priority = 1.5; n->bubbleDown(); RandomizedNode *p = n->parent(); if (p->lchild() == n) p->_lchild = NULL; else p->_rchild = NULL; if ( win == n) win = n->prev(); n->Node::remove(); delete n; --_length; } // ......................................................... template T RandomizedSearchTree::remove( T val) { T v = find(val); if (v) { remove(); return v; } return NULL; } //////////////////////////////////////////////////////////// template List *arrayToList(T a[], int n) { List *s = new List; for ( int i=0; iappend(a[i]); return s; } //////////////////////////////////////////////////////////// template T leastItem(List &s, int (*cmp)(T,T) ) { if (s.length()==0) return NULL; T v=s.first(); for (s.next(); !s.isHead(); s.next() ) if ( (*cmp)(s.val(), v) < 0) v=s.val(); return v; } #endif // _LLIST_H_