#include
#include
#include
#include
#include
#include
#include "avltree.hpp"
using namespace std;
using CS202::AVLTree;
using CS202::AVLNode;
AVLTree& AVLTree::operator= (const AVLTree &t)
{
(void) t;
return *this;
}
/* I simply took Insert and Delete from their binary search tree
implementations. They aren't correct for AVL trees, but they are
good starting points. */
bool AVLTree::Insert(const string &key, void *val)
{
AVLNode *parent;
AVLNode *n;
parent = sentinel;
n = sentinel->right;
/* Find where the key should go. If you find the key, return false. */
while (n != sentinel) {
if (n->key == key) return false;
parent = n;
n = (key < n->key) ? n->left : n->right;
}
/* At this point, parent is the node that will be the parent of the new node.
Create the new node, and hook it in. */
n = new AVLNode;
n->key = key;
n->val = val;
n->parent = parent;
n->height = 1;
n->left = sentinel;
n->right = sentinel;
/* Use the correct pointer in the parent to point to the new node. */
if (parent == sentinel) {
sentinel->right = n;
} else if (key < parent->key) {
parent->left = n;
} else {
parent->right = n;
}
/* Increment the size */
size++;
return true;
}
bool AVLTree::Delete(const string &key)
{
AVLNode *n, *parent, *mlc;
string tmpkey;
void *tmpval;
/* Try to find the key -- if you can't return false. */
n = sentinel->right;
while (n != sentinel && key != n->key) {
n = (key < n->key) ? n->left : n->right;
}
if (n == sentinel) return false;
/* We go through the three cases for deletion, although it's a little
different from the canonical explanation. */
parent = n->parent;
/* Case 1 - I have no left child. Replace me with my right child.
Note that this handles the case of having no children, too. */
if (n->left == sentinel) {
if (n == parent->left) {
parent->left = n->right;
} else {
parent->right = n->right;
}
if (n->right != sentinel) n->right->parent = parent;
delete n;
size--;
/* Case 2 - I have no right child. Replace me with my left child. */
} else if (n->right == sentinel) {
if (n == parent->left) {
parent->left = n->left;
} else {
parent->right = n->left;
}
n->left->parent = parent;
delete n;
size--;
/* If I have two children, then find the node "before" me in the tree.
That node will have no right child, so I can recursively delete it.
When I'm done, I'll replace the key and val of n with the key and
val of the deleted node. You'll note that the recursive call
updates the size, so you don't have to do it here. */
} else {
for (mlc = n->left; mlc->right != sentinel; mlc = mlc->right) ;
tmpkey = mlc->key;
tmpval = mlc->val;
Delete(tmpkey);
n->key = tmpkey;
n->val = tmpval;
return true;
}
return true;
}
/* You need to write these two. You can lift them verbatim from your
binary search tree lab. */
vector AVLTree::Ordered_Keys() const
{
vector rv;
return rv;
}
void AVLTree::make_key_vector(const AVLNode *n, vector &v) const
{
(void) n;
(void) v;
}
size_t AVLTree::Height() const
{
return 0;
}
/* You need to write this to help you with the assignment overload.
It makes a copy of the subtree rooted by n. That subtree is part
of a different tree -- the copy will be part of the tree that
is calling the method. */
AVLNode *AVLTree::recursive_postorder_copy(const AVLNode *n) const
{
(void) n;
return NULL;
}