Пример #1
0
// Returns true if the value was found and removed, false if it was not found
bool HW4AVL::Remove(int dataValue)
{
	if (!m_root)
	{
		return false;
	}

	// Implement (the rest of) this function
	// Remember to balance before returning
		Node* parent = NULL;
	Node* deleteMe = m_root;
	while (true)
	{
		if (deleteMe->Data == dataValue)
		{
			break;
		}

		else if (dataValue > deleteMe->Data)
		{
			if (deleteMe->Right)
			{
				parent = deleteMe;
				deleteMe = deleteMe->Right;
			}
			else
			{
				return false;
			}
		}
		else
		{
			if (deleteMe->Left)
			{
				parent = deleteMe;
				deleteMe = deleteMe->Left;
			}
			else
			{
				return false;
			}
		}
	}

	// We have the node we want to delete and its parent

	// Case 1: It's a leaf
	if (NULL == deleteMe->Left && NULL == deleteMe->Right)
	{
		if (parent)
		{
			parent->DeleteChild(deleteMe);
		}
		else
		{
			delete m_root;
			m_root = NULL;
		}

	}

	// Case 2a: Null left child, non-null right
	else if (NULL == deleteMe->Left)
	{
		if (parent)
		{
			parent->ReplaceAndDeleteChild(deleteMe, deleteMe->Right);
		}
		else
		{
			m_root = m_root->Right;
			delete deleteMe;
		}
	}

	// Case 2b: Null right child, non-null left
	else if (NULL == deleteMe->Right)
	{
		if (parent)
		{
			parent->ReplaceAndDeleteChild(deleteMe, deleteMe->Left);
		}
		else
		{
			m_root = m_root->Left;
			delete deleteMe;
		}
	}

	// Case 3: Non-null left and right children
	else
	{
		// (Arbitrary) Find the min in the right subtree
		Node* min = deleteMe->Right;
		while (min->Left)
		{
			min = min->Left;
		}

		int minValue = min->Data;
		Remove(minValue);
		deleteMe->Data = minValue;
		return true;
	}
	// Check for balance & Balance if necessary
	int lHeight = 0, rHeight = 0;
	if(parent != NULL)
	{
		lHeight = Height(parent->Left);
		rHeight = Height(parent->Right);
	}
	while(parent != NULL && (lHeight-rHeight) != 2 && (rHeight-lHeight) != 2)
	{
		parent = parent->Parent;
		if(parent != NULL)
		{
			lHeight = Height(parent->Left);
			rHeight = Height(parent->Right);
		}
	}
	if(parent != NULL) //Need to balance
	{
		Node* child = NULL;
		if(Height(parent->Left) > Height(parent->Right))
		{
			child = parent->Left;
		}
		else
		{
			child = parent->Right;
		}
		Node* grandChild = NULL;
		if(Height(child->Left) > Height(child->Right))
		{
			grandChild = child->Left;
		}
		else
		{
			grandChild = child->Right;
		}

		if(child->Data < parent->Data)
		{
			if(grandChild->Data < child->Data)
			{
				rotateLeft(&parent);
			}
			else
			{
				rotateLeftTwice(&parent);
			}
		}
		else
		{
			if(grandChild->Data > child->Data)
			{
				rotateRight(&parent);
			}
			else
			{
				rotateRightTwice(&parent);
			}
		}
	}
	return true;
}