123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706 |
- template <typename K, typename V>
- SplayTreeNode<K,V>*
- SplayTree<K,V>::insertInSubtree(SplayTreeNode<K,V>* current, K key, V value, bool* inserted, bool* skip) {
- if (current == NULL){
- size++;
- *inserted = true;
- *skip = true;
- return new SplayTreeNode<K, V>(key, value);
- }
- else if (key == current->key && !(*inserted)){
- throw std::runtime_error("SplayTree::insertInSubtree" \
- "called on key already in tree.");
- }
- else if (key < current->key){
- current->left = insertInSubtree(current->left, key, value, inserted, skip);
- }
- else if (key > current->key){
- current->right = insertInSubtree(current->right, key, value, inserted, skip);
- }
- if (current->key == root->key && *inserted) {
- return splay(current, key);
- }
- else if (*skip && (current != root) && *inserted) {
- *skip = false;
- return current;
- }
- else {
- *skip = true;
- return splay(current, key);
- }
- }
- /**
- * This recursive helper function updates key-value pair in the subtree
- * of the tree, or throws a runtime_error if the key is not present.
- */
- /*
- template <typename K, typename V>
- void SplayTree<K,V>::updateInSubtree(SplayTreeNode<K,V>* current, K key, V value) {
-
- if (current == NULL){
- throw std::runtime_error("Key not found in SplayTree::updateInSubtree.");
- }
- else if (key == current->key){
- current->value = value;
- }
- else if (key < current->key){
- updateInSubtree(current->left, key, value);
- }
- else if (key > current->key){
- updateInSubtree(current->right, key, value);
- }
- return;
- }
- */
- /**
- * This recursive helper function removes a key-value pair from a subtree
- * of the tree, or throws a runtime_error if that key was not present.
- *
- * It returns a pointer to the root of the subtree. This root is often
- * the node that was passed as an argument to the function (current) but
- * might be a different node if current contains the key we are removing
- * from the tree.
- */
- template <typename K, typename V>
- SplayTreeNode<K,V>*
- SplayTree<K,V>::removeFromSubtree(SplayTreeNode<K,V>* current, K key) {
- if (current == NULL) {
- throw std::runtime_error("SplayTree::remove called on key not in tree.");
- }
- else if (key == current->key) { // We've found the node to remove
- if ((current->left == NULL) && (current->right == NULL)) {
- size--;
- delete current;
- return NULL;
- }
- else if (current->left == NULL) {
- SplayTreeNode<K,V>* tempNode = current->right;
- delete current;
- size--;
- return tempNode;
- }
- else if (current->right == NULL) {
- SplayTreeNode<K,V>* tempNode = current->left;
- delete current;
- size--;
- return tempNode;
- }
- else {
- SplayTreeNode<K,V>* minimum = current->right;
- while (minimum->left != NULL) {
- minimum = minimum->left;
- }
- current->key = minimum->key;
- current->value = minimum->value;
- current->right = removeFromSubtree(current->right, current->key);
- }
- }
- else if (key < current->key) {
- current->left = removeFromSubtree(current->left, key);
- }
- else {
- current->right = removeFromSubtree(current->right, key);
- }
- return current;
- }
- /**
- * Returns true if a key is contained in a subtree of the tree, and
- * false otherwise.
- */
- template <typename K, typename V>
- bool SplayTree<K,V>::containsInSubtree(SplayTreeNode<K,V>* current, K key, bool * skip) {
- /* if (current == NULL){
- return false;
- }
- else if (key == current->key){
- return true;
- }
- else if (key < current->key){
- if (containsInSubtree(current->left, key)){
- currentsplay(current->left);
- return true;
- }
- else{
- return false;
- }
- }
- else {
- if (containsInSubtree(current->right, key)){
- current->right = splay(current->right);
- return true;
- }
- else{
- return false;
- }
- }
- */
- if (current == NULL){
- return false;
- }
-
- else if ((current->key == root->key) && (current->key == key)){
- return true;
- }
- else if (current->left == NULL && current->right == NULL &&
- current->key != key){
- return false;
- }
- else if (current->left == NULL){
- if (current->right->key == key){
- if (current->key == root->key){
- root = splay(root, key);
- }
- return true;
- }
- else if (current->key > key){
- return false;
- }
- else if (current->key < key){
- if (containsInSubtree(current->right, key, skip)){
- if (*skip == true) {
- *skip = false;
- }
- else {
- current->right = splay(current->right, key);
- }
- if (current->key == root->key){
- root = splay(root, key);
- }
- return true;
- }
- else{
- return false;
- }
- }
- }
- else if (current->right == NULL){
- if (current->left->key == key){
- if (current->key == root->key){
- root = splay(root, key);
- }
- return true;
- }
- else if (current->key < key){
- return false;
- }
- else if (current->key > key){
- if (containsInSubtree(current->left, key, skip)){
- if (*skip == true) {
- *skip = false;
- }
- else {
- current->left = splay(current->left, key);
- }
- if (current->key == root->key){
- root = splay(root, key);
- }
- return true;
- }
- else{
- return false;
- }
- }
- }
- else{
- if (current->right->key == key){
- if (current->key == root->key){
- root = splay(root, key);
- }
- return true;
- }
- else if (current->left->key == key){
- if (current->key == root->key){
- root = splay(root, key);
- }
- return true;
- }
- else if (current->key > key){
- if (containsInSubtree(current->left, key, skip)){
- if (*skip == true) {
- *skip = false;
- }
- else {
- current->left = splay(current->left, key);
- }
- if (current->key == root->key){
- root = splay(root, key);
- }
- return true;
- }
- else{
- return false;
- }
- }
- else if (current->key < key){
- if (containsInSubtree(current->right, key, skip)){
- if (*skip == true) {
- *skip = false;
- }
- else {
- current->right = splay(current->right, key);
- }
- if (current->key == root->key){
- root = splay(root, key);
- }
- return true;
- }
- else{
- return false;
- }
- }
- }
- throw std::runtime_error("failed call to SplayTree::containsInSubtree");
- }
- /**
- * Given a key, returns the value for that key from a subtree of the tree.
- * Throws a runtime_error if the key is not in the subtree.
- */
- /*
- template <typename K, typename V>
- V SplayTree<K,V>::findInSubtree(SplayTreeNode<K,V>* current, K key) {
- if (current == NULL) {
- throw std::runtime_error("SplayTree::findInSubtree called on an empty tree");
- }
- else if (key == current->key) {
- return current->value;
- }
- else if (key < current->key) {
- return findInSubtree(current->left, key);
- }
- else {
- return findInSubtree(current->right, key);
- }
- }
- */
- /**
- * Returns the largest key in a subtree of the tree.
- */
- template <typename K, typename V>
- K SplayTree<K,V>::getMaxInSubtree(SplayTreeNode<K,V>* current) {
- if (current->right == NULL) {
- return current->key;
- }
- return getMaxInSubtree(current->right);
- }
- /**
- * Returns the smallest key in a subtree of the tree.
- */
- template <typename K, typename V>
- K SplayTree<K,V>::getMinInSubtree(SplayTreeNode<K,V>* current) {
- if (current->left == NULL) {
- return current->key;
- }
- return getMinInSubtree(current->left);
- }
- /*
- * Returns the height of a subtree of the tree, or -1 if the subtree
- * is empty.
- *
- template <typename K, typename V>
- int SplayTree<K,V>::getHeightOfSubtree(SplayTreeNode<K,V>* current) {
- if (current == NULL) {
- return -1;
- }
- int l = getHeightOfSubtree(current->left);
- int r = getHeightOfSubtree(current->right);
- if (l >= r) {
- return ++l;
- }
- else
- return ++r;
- }
- */
- /**
- * Recursively builds a post-order iterator for a subtree of the tree.
- */
- template <typename K, typename V>
- void SplayTree<K,V>::buildPostOrder(SplayTreeNode<K,V>* current,
- Queue< Pair<K,V> >* it) {
- if (current == NULL) {
- return;
- }
- buildPostOrder(current->left, it);
- buildPostOrder(current->right, it);
- it->enqueue( Pair<K,V>(current->key, current->value) );
- }
- /**
- * Recursively builds a pre-order iterator for a subtree of the tree.
- */
- template <typename K, typename V>
- void SplayTree<K,V>::buildPreOrder(SplayTreeNode<K,V>* current,
- Queue< Pair<K,V> >* it) {
- if (current == NULL){
- return;
- }
- it->enqueue( Pair<K,V>(current->key, current->value) );
- buildPreOrder(current->left, it);
- buildPreOrder(current->right, it);
- }
- /**
- * Recursively builds an in-order iterator for a subtree of the tree.
- */
- template <typename K, typename V>
- void SplayTree<K,V>::buildInOrder(SplayTreeNode<K,V>* current,
- Queue< Pair<K,V> >* it) {
- if (current == NULL){
- return;
- }
- buildInOrder(current->left, it);
- it->enqueue( Pair<K,V>(current->key, current->value) );
- buildInOrder(current->right, it);
- }
- /**
- * Performs a post-order traversal of the tree, deleting each node from the
- * heap after we have already traversed its children.
- */
- template <typename K, typename V>
- void SplayTree<K,V>::traverseAndDelete(SplayTreeNode<K,V>* current) {
- if (current == NULL) {
- return; //nothing to delete
- }
- traverseAndDelete(current->left);
- traverseAndDelete(current->right);
- delete current;
- }
- /* The four rotations needed to fix each of the four possible imbalances
- * in an SplayTree
- * (1) Right rotation for a left-left imbalance
- * (2) Left rotation for a right-right imbalance
- * (3) LeftRight rotation for left-right imbalance
- * (4) RightLeft rotation for a right-left imbalance
- */
- template<typename K, typename V>
- SplayTreeNode<K,V>* SplayTree<K,V>::rightRotate(SplayTreeNode<K,V>* current) {
- SplayTreeNode<K,V>* b = current;
- SplayTreeNode<K,V>* d = current->left;
- current = d;
- if (d->right == NULL){
- b->left = NULL;
- }
- else{
- b->left = d->right;
- }
- d->right = b;
- return current;
- }
- template<typename K, typename V>
- SplayTreeNode<K,V>* SplayTree<K,V>::leftRotate(SplayTreeNode<K,V>* current) {
- SplayTreeNode<K,V>* b = current;
- SplayTreeNode<K,V>* d = current->right;
- current = d;
- if (d->left == NULL){
- b->right = NULL;
- }
- else{
- b->right = d->left;
- }
- d->left = b;
- return current;
- }
- template<typename K, typename V>
- SplayTreeNode<K,V>* SplayTree<K,V>::rightLeftRotate(SplayTreeNode<K,V>* current) {
- current->right = rightRotate(current->right);
- return leftRotate(current);
- }
- template<typename K, typename V>
- SplayTreeNode<K,V>* SplayTree<K,V>::leftRightRotate(SplayTreeNode<K,V>* current) {
- current->left = leftRotate(current->left);
- return rightRotate(current);
- }
- template<typename K, typename V>
- SplayTreeNode<K,V>* SplayTree<K,V>:: rightRightRotate(SplayTreeNode<K,V>* current) {
- current = rightRotate(current);
- return rightRotate(current);
- }
- template<typename K, typename V>
- SplayTreeNode<K,V>* SplayTree<K,V>:: leftLeftRotate(SplayTreeNode<K,V>* current) {
- current = leftRotate(current);
- return leftRotate(current);
- }
- template<typename K, typename V>
- SplayTreeNode<K,V>* SplayTree<K,V>::splay(SplayTreeNode<K,V>* parent, K key){
- if (parent == NULL){
- throw std::runtime_error("1 Splay function failure in SplayTree::splay.");
- }
- else {
- if (parent->right == NULL){
- if (parent->left == NULL) {
- throw std::runtime_error("2 Splay function failure in SplayTree::splay.");
- }
- else if (parent->left->key == key){
- return rightRotate(parent);
- }
- else {
- if (parent->left->left == NULL && parent->left->right == NULL) {
- throw std::runtime_error("3 Splay function failure in SplayTree::splay.");
- }
- else if (parent->left->right == NULL) {
- //cout << "parent->left->left = " << parent->left->left->key << " key = " << key << " parent->left = " << parent->left->key;
- //cout << " parent = " << parent->key << " " << parent->left->left->left->key << endl;
- if (parent->left->left->key == key) {
- return rightRightRotate(parent);
- }
- else {
- throw std::runtime_error("4 Splay function failure in SplayTree::splay.");
- }
- }
- else if (parent->left->left == NULL) {
- if (parent->left->right->key == key) {
- return leftRightRotate(parent);
- }
- else {
- throw std::runtime_error("5 Splay function failure in SplayTree::splay.");
- }
- }
- else {
- if (parent->left->right->key == key) {
- return leftRightRotate(parent);
- }
- else if (parent->left->left->key == key) {
- return rightRightRotate(parent);
- }
- else {
- throw std::runtime_error("6 Splay function failure in SplayTree::splay.");
- }
- }
- }
- }
- else if (parent->left == NULL) {
- if (parent->right == NULL) {
- throw std::runtime_error("2 Splay function failure in SplayTree::splay.");
- }
- else if (parent->right->key == key){
- return leftRotate(parent);
- }
- else{
- if (parent->right->left == NULL && parent->right->right == NULL) {
- throw std::runtime_error("7 Splay function failure in SplayTree::splay.");
- }
- else if (parent->right->left == NULL) {
- if (parent->right->right->key == key) {
- return leftLeftRotate(parent);
- }
- else {
- throw std::runtime_error("8 Splay function failure in SplayTree::splay.");
- }
- }
- else if (parent->right->right == NULL) {
- if (parent->right->left->key == key) {
- return rightLeftRotate(parent);
- }
- else {
- throw std::runtime_error("9 Splay function failure in SplayTree::splay.");
- }
- }
- else {
- if (parent->right->left->key == key) {
- return rightLeftRotate(parent);
- }
- else if (parent->right->right->key == key) {
- return leftLeftRotate(parent);
- }
- else {
- throw std::runtime_error("10 Splay function failure in SplayTree::splay.");
- }
- }
- }
- }
- else {
- if (parent->left->key == key) {
- return rightRotate(parent);
- }
- else if (parent->right->key == key) {
- return leftRotate(parent);
- }
- else if (parent->key > key){
- if (parent->left->key > key){
- if (parent->left->left == NULL){
- throw std::runtime_error("Splay function failure in SplayTree::splay.");
- }
- else if (parent->left->left->key == key){
- return rightRightRotate(parent);
- }
- else{
- throw std::runtime_error("Splay function failure in SplayTree::splay.");
- }
- }
- else{
- if (parent->left->right == NULL){
- throw std::runtime_error("Splay function failure in SplayTree::splay.");
- }
- else if (parent->left->right->key == key){
- return leftRightRotate(parent);
- }
- else{
- throw std::runtime_error("Splay function failure in SplayTree::splay.");
- }
- }
- }
- else if (parent->key < key){
- if (parent->right->key > key){
- if (parent->right->left == NULL){
- throw std::runtime_error("Splay function failure in SplayTree::splay.");
- }
- else if (parent->right->left->key == key){
- return rightLeftRotate(parent);
- }
- else{
- throw std::runtime_error("Splay function failure in SplayTree::splay.");
- }
- }
- else{
- if (parent->right->right == NULL){
- throw std::runtime_error("Splay function failure in SplayTree::splay.");
- }
- else if (parent->right->right->key == key){
- return leftLeftRotate(parent);
- }
- else{
- throw std::runtime_error("Splay function failure in SplayTree::splay.");
- }
- }
- }
- throw std::runtime_error("12 Splay function failure in SplayTree::splay.");
- }
- }
- }
- /**
- * Returns the height of a subtree of the tree, or -1 if the subtree
- * is empty.
- */
- template <typename K, typename V>
- int SplayTree<K,V>::getHeightOfSubtree(SplayTreeNode<K,V>* current) {
- if (current == NULL) {
- return -1;
- }
- int l = getHeightOfSubtree(current->left);
- int r = getHeightOfSubtree(current->right);
- if (l >= r) {
- return ++l;
- }
- else
- return ++r;
- }
- /*
- template<typename K, typename V>
- SplayTreeNode<K,V>* SplayTree<K,V>::findInSubtree(SplayTreeNode<K,V>* current,
- K toSplay){
- if (current == NULL){
- throw std::runtime_error("Code1: Nonexistent node referenced in SplayTree::splay.");
- }
- else if ((current->left == NULL) && (current->right == NULL)){
-
- if (current->key == toSplay){
- return current;
- }
- throw std::runtime_error("Code2: Nonexistent node referenced in SplayTree::splay.");
- }
- else{
- if (current->left == NULL){
- if (current->right->key == toSplay){
- return leftRotate(current);
- }
- else if (current->key < toSplay){
- current->right = findInSubtree(current->right, toSplay);
- return leftRotate(current);
- }
- }
- else if (current->right == NULL){
- if (current->left->key == toSplay){
- return rightRotate(current);
- }
- else if (current->key > toSplay){
- current->left = findInSubtree(current->left, toSplay);
- return rightRotate(current);
- }
- }
-
- else{
- if (current->right->key == toSplay){
- return leftRotate(current);
- }
- else if (current->left->key == toSplay){
- return rightRotate(current);
- }
- else if (current->key > toSplay){
- current->left = findInSubtree(current->left, toSplay);
- return rightRotate(current);
- }
- else if (current->key < toSplay){
- current->right = findInSubtree(current->right, toSplay);
- return leftRotate(current);
- }
- }
- throw std::runtime_error("Code3: Nonexistent node referenced in SplayTree::splay.");
- }
- }
- */
- /*
- template<typename K, typename V>
- SplayTreeNode<K,V>* SplayTree<K,V>::splay(SplayTreeNode<K,V>* toSplay){
- if (root->key == toSplay->key){
- return root;
- }
- else{
- root = findInSubtree(root, toSplay);
- }
- }
- */
|