예제 #1
0
// If node X is a leaf or has only one child, skip to step 5. (node Z will be node X)
// Otherwise, determine node Y by finding the largest node in node X's left sub tree (in-order predecessor) or the smallest in its right sub tree (in-order successor).
// Replace node X with node Y (remember, tree structure doesn't change here, only the values). In this step, node X is essentially deleted when its internal values were overwritten with node Y's.
// Choose node Z to be the old node Y.
// Attach node Z's subtree to its parent (if it has a subtree). If node Z's parent is null, update root. (node Z is currently root)
// Delete node Z.
// Retrace the path back up the tree (starting with node Z's parent) to the root, adjusting the balance factors as needed.
// As with all binary trees, a node's in-order successor is the left-most child of its right subtree, and a node's in-order predecessor is the right-most child of its left subtree. 
// In either case, this node will have zero or one children. Delete it according to one of the two simpler cases above.
// Removes one element from the dictionary
bool
AVLDictionary::removeElement(KeyType key)
{
	if (debug) {
		printf("------------------------------------\n");
		printf("removeElement(\"%s\")\n",  key);
		printf("---------- Before -----------------\n");
		printNode("", root, 0);
	}

	//need to subsitute root with node that comes immediately before or after
	// AVLNode *current = (AVLNode*)findNode(key);
	AVLNode *current = root;
	while (current != NULL)	{
		if (strcmp(current->key, key) == 0) {
			break;
		} else if (strcmp(current->key, key) > 0) {
			current = current->left;
		} else {
			current = current->right;
		}
	}
	
	if (current == NULL) {
		return false;
	}

	AVLNode *parent = NULL;
	if (current != root) {
		parent = current->parent;
	} else { //is root
		current->left = current->right->parent;
	}
	// if(current == parent->right) {
 //        parent->right = current->right;
	// } else {
 //        parent->left = current->right;
	// }

	if (current->left == NULL && current->right == NULL) { //no children, just delete?
		if (current == parent->right) {
			parent->right = NULL;
		} else {
			parent->left = NULL;
		}
		
		delete current;
		restructure(parent);
	} else if (current->left == NULL) {
		if (current == parent->right) {
			parent->right = NULL;
			parent->right = current->right;
			parent->right->height = current->right->height;
			delete current;
			current = NULL;
			restructure(parent);
		} else {
			parent->left = NULL;
			parent->left = current->right;
			parent->left->height = current->right->height;
			restructure(parent);
			delete current;
			current = NULL;
		}
    	// restructure(current->right);
	} else if (current->right == NULL) {
		if (current == parent->right) {
			parent->right = NULL;
			parent->right = current->left;
			parent->right->height = current->left->height;
			// current = current->right;
			restructure(parent);
			delete current;
			current = NULL;
			
		} else {
			parent->left = NULL;
			parent->left = current->left;
			parent->left->height = current->left->height;
			restructure(parent);
			delete current;
			current = NULL;
			
			// current = current->right;
		}
		// delete current;
		// restructure(parent);
		// parent->left = current->right;
		// current = current->right;
		
		// restructure(current);
		// restructure(current->left);
	} else { //is internal
		AVLNode *preorder = current->left;

		while (preorder->right != NULL) {
			preorder = preorder->right;
		}

		current->key = preorder->key;
		current->data = preorder->data;
		
		current = preorder;

		if (current->left == NULL) {
			if (current->parent->right == current) {
				current->parent->right = current->right;
			} else {
				current->parent->left = current->right;
			}
		} else {
			if (current->parent->right == current) {
				current->parent->right = current->left;
			} else {
				current->parent->left = current->left;
			}
		}

		restructure(current->parent);
		delete current;
	}
	
	if (debug) {
		printf("---------- After -----------------\n");
		printNode("", root, 0);

		checkRecursive(root);
	}
	
	return true;
}
예제 #2
0
// Add a record to the dictionary. Returns false if key already exists
bool
AVLDictionary::addRecord( KeyType key, DataType data) {
	if ( debug) {
		printf("------------------------------------\n");
		printf("addRecord(\"%s\",%d)\n",  key, (int)data);
		printf("---------- Before -----------------\n");
		printNode("", root, 0);
	}

	//find node with that key, if any
	//overwrite data if found
	AVLNode *current = root;
	AVLNode *prev = NULL;

	while (current != NULL)	{
		prev = current;
		if (strcmp(key, current->key) == 0) {
		// key == current->key) //
			//found, overwrite data
			current->data = data;
			return false;
		} else if (strcmp(key, current->key) > 0) {
		// (key - current->key > 0)
		//key is in right subtree
			current = current->right;
		} else {	//key is in left subtree
			current = current->left;
		}
	} //did not find key in tree, and prev points to parent node where new node will be inserted
	
	AVLNode *newNode = new AVLNode();
	newNode->key = strdup(key); //use strdup if key is const char*
	newNode->data = data; 
	newNode->height = 1;
	newNode->left = NULL;
	newNode->right = NULL;
	newNode->parent = prev;

	if (prev == NULL) {	//tree is empty, assign to root
		root = newNode;
		nElements++;
		return true;
	}

	if (strcmp(key, prev->key) > 0) {	//attach to right
		prev->right = newNode;
	} else {
		prev->left = newNode;
	}
	
	//adjust heights of above subtrees, path from inserted node to root
	AVLNode *m = newNode->parent;

	while (m != NULL) {//go up
		//get maxHeight of left and right children
		int maxHeight = 0;

		if (m->left != NULL) {
			maxHeight = m->left->height;
		}

		if (m->right != NULL && maxHeight < m->right->height) {
			maxHeight = m->right->height;
		}
		//update height of m
		m->height = 1 + maxHeight;
		m = m->parent;
	}

	//at this point, the newnode is in place and height has been adjusted for correctness, 
	//however, may not fulfill AVL tree conditions, because of potential height differences 
	//in subtrees (ie difference in height of left and right > 1)
	//restructure beginning at inserted node

	//Find node to insert into 
	//Node does not exist. Create it.
	//Height might not be valid anymore.
	//We need to restructure .

	if ( debug) {
		printf("---------- Before Restructure -----------------\n");
		printNode("", root, 0);
	}
	
	// Call restructure
	restructure(newNode);

	if (debug) {
		checkRecursive(root);
		
		printf("---------- After Restructure -----------------\n");
		printNode("", root, 0);
	}

	nElements++;
	return true;
}
예제 #3
0
void
AVLDictionary::checkRecursive(AVLNode * node) {
	if (node == NULL) {
		return;
	}

	if (node->left!=NULL) {
		// Make sure that it is sorted
		if ( strcmp(node->key, node->left->key) <= 0) {
			fprintf(stderr,
				"*** NOT SORTED: parent->key=\"%s\" <= left->key=\"%s\"\n",
			       node->key, node->left->key);
			assert(0);
		}
	}

	if (node->right!=NULL) {
		// Make sure that it is sorted
		if ( strcmp(node->key, node->right->key) >= 0) {
			fprintf(stderr,
				"*** NOT SORTED: parent->key=\"%s\" >= right->key=\"%s\"\n",
				node->key, node->right->key);
			assert(0);
		}
	}

	checkRecursive(node->left);
	checkRecursive(node->right);

	// Check height
	int lHeight = 0;
	if (node->left!=0) {
		lHeight = node->left->height;
	}

	int rHeight = 0;
	if (node->right!=0) {
		rHeight = node->right->height;
	}

	int diff = lHeight - rHeight;
	if (diff<0) {
		diff = - diff;
	}

	if (diff>1) {
		fprintf(stderr,
			"*** HEIGHT DIFFERENCE > 1: key=\"%s\" lheight=%d rheight=%d\n",
			node->key, lHeight, rHeight);
		assert(0);
	}

	// Compute height
	int maxHeight = lHeight;
	if (maxHeight<rHeight) {
		maxHeight = rHeight;
	}

	if (node->height != maxHeight + 1) {
		fprintf(stderr,
			"*** WRONGH HEIGHT: key=\"%s\" height=%d should be %d\n",
			node->key, node->height, maxHeight + 1);
		assert(0);
	}
}
예제 #4
0
//
// Goes over the nodes in the tree to verify that the height and keys 
// of the AVL tree are correct. It prints a message and exits if it is not a
// valid AVL tree.
//
void
AVLDictionary::check()
{
	checkRecursive(root);
}
예제 #5
0
// Removes one element from the dictionary
bool
AVLDictionary::removeElement(KeyType key)
{
	if (debug)
	{
		printf("------------------------------------\n");
		printf("removeElement(\"%s\")\n",  key);
		printf("---------- Before -----------------\n");
		printNode("", root, 0);
	}

	AVLNode *node;
	node = findNode(key);
	
	if (node == NULL)
	{
     	return false;
    }
   
	if (node->left == NULL && node->right == NULL)
	{
		if ( node == node->parent->left)
		{
			node->parent->left = NULL;
		}
		else
		{
			node->parent->right = NULL;
		}

		AVLNode *m;
		m = node->parent;
		
		while(m != NULL)
		{
			int maxheight = 0;
			if(m->left != NULL)
			{
				maxheight = m->left->height;
			}
			if (m->right != NULL && maxheight < m->right->height)
			{
				maxheight = m->right->height;
			}
			m->height = maxheight +1;
			m = m->parent;
		}

		restructure(node->parent);

		delete node;
    }
	else if (node->left == NULL)
	{
	    AVLNode temp;
   	
     	temp.height = node->height;
     	strcpy((char*)temp.key, node->key);
     	temp.data = node->data;
      
     	node->height = node->right->height;
     	strcpy((char*)node->key, node->right->key);
     	node->data = node->right->data;
 
     	node->right->height = temp.height;
     	strcpy((char*)node->right->key, temp.key);
     	node->right->data = temp.data;
   
     	delete node->right;
   
     	node->right = NULL;   
   
     	AVLNode *m = node->parent;
     	while(m != NULL)
		{
     		int maxheight = 0;
     		if(m->left != NULL)
			{
     			maxheight = m->left->height;
     		}
     		if (m->right != NULL && maxheight < m->right->height)
			{
     			maxheight = m->right->height;
     		}
     		m->height = maxheight +1;
     		m = m->parent;
   
     	}
   
     	restructure(node);
    }
	else if (node->right == NULL)
	{
     	AVLNode temp;
   
     	temp.height = node->height;
     	strcpy((char*)temp.key, node->key);
     	temp.data = node->data;
 
     	node->height = node->left->height;
     	strcpy((char*)node->key, node->left->key);
     	node->data = node->left->data;
   
     	node->left->height = temp.height;
     	strcpy((char*)node->left->key, temp.key);
     	node->left->data = temp.data;
   
     	delete node->left;
   
     	node->left = NULL;   	
   
     	AVLNode *m;
		m = node->parent;
		
     	while(m != NULL)
		{
     		int maxheight = 0;
     		if( m->left != NULL)
			{
     			maxheight = m->left->height;
     		}
     		if (m->right != NULL && maxheight < m->right->height)
			{
     			maxheight = m->right->height;
     		}
     		m->height = maxheight +1;
     		m = m->parent;
   
     	}
   
     	restructure(node);
    }
	else
	{
		AVLNode *replacement;   
		replacement = node->left;
		
     	if (replacement->right == NULL)
		{
     		replacement = node->right;
     		while(replacement->left != NULL)
			{
     			replacement = replacement->left;
     		}
     	}
		else
		{
			while (replacement->right != NULL)
			{
     			replacement = replacement->right;
     		}
   
     	}
		
		AVLNode temp;
       
		temp.height = node->height;
     	strcpy((char*)temp.key, node->key);
     	temp.data = node->data;
   
     	node->height = replacement->height;
     	strcpy((char*)node->key, replacement->key);
     	node->data = replacement->data;
 	
     	replacement->height = temp.height;
     	strcpy((char*)replacement->key, temp.key);
     	replacement->data = temp.data;
   	
     	AVLNode *n;
		n = replacement->parent;
		
     	if (n != NULL)
		{
			if (replacement == n->left)
			{
     			n->left = NULL;   
     			delete replacement;
     		}
			else
			{
     			n->right = NULL;
     			delete replacement;
     		}
   
			AVLNode *m = n;
			while(m != NULL)
			{
				int maxheight = 0;
				if(m->left != NULL)
				{
					maxheight = m->left->height;
				}
				if (m->right != NULL && maxheight < m->right->height)
				{
					maxheight = m->right->height;
				}
				m->height = maxheight +1;
				m = m->parent;   
			}
	   
			restructure(n);
		}
	}
	
	nElements--;
	
	if (debug)
	{
		printf("---------- After -----------------\n");
		printNode("", root, 0);

		checkRecursive(root);
	}
	
	return true;
}
예제 #6
0
// Add a record to the dictionary. Returns false if key already exists
bool
AVLDictionary::addRecord( KeyType key, DataType record)
{
	if (debug)
	{
		printf("------------------------------------\n");
		printf("addRecord(\"%s\",%d)\n",  key, record);
		printf("---------- Before -----------------\n");
		printNode("", root, 0);
	}
	
	AVLNode *n;
	n = new AVLNode();
	
    n->key = key;
    n->data = record;
    n->height = 1;
    n->left = NULL;
    n->right = NULL;
    n->parent = NULL;

    if(root == NULL)
	{
        root = n;
		nElements++;
		
        return true;
    }

    AVLNode *curr;
	curr = root;
	
    AVLNode *prev;
	prev = NULL;
	
    while(curr != NULL)
	{
        prev = curr;
        if (strcmp(key, curr->key) < 0)
		{
            curr = curr->left;
        }
        else if (strcmp(key, curr->key) > 0)
		{
            curr = curr->right;
        }
        else
		{
            curr->data = record;
            return false;
        }
    }

    if (strcmp(key, prev->key) < 0)
	{
        prev->left = n;
    }
    else
	{
        prev->right = n;
    }

    n->parent = prev;

    AVLNode *m;
	m = n->parent;
	
    while(m != NULL)
	{
        int maxheight = 0;
        if(m->left != NULL)
            maxheight = m->left->height;
        if(m->right != NULL && maxheight < m->right->height)
            maxheight = m->right->height;
        m->height = 1+maxheight;
        m = m->parent;
    }

	if (debug)
	{
		printf("---------- Before Restructure -----------------\n");
		printNode("", root, 0);
	}
	
	restructure(n);

	if (debug)
	{
		checkRecursive(root);
		
		printf("---------- After Restructure -----------------\n");
		printNode("", root, 0);
	}
	
	nElements++;
		
	return true;
}