#pragma once
#include<algorithm>
using namespace std;
//BinarySearchTree class
//construction: zero parameter
//
/*
void insert(x) -->Insert x
void remove(x) -->Remove x
bool contains(x)-->Return true if x is present
Comparable findMin()-->return smallest item
Comparable findMax()-->return largest item
boolean isEmpty()-->return true if empty; else false
void make empty()-->remove all items
void printTree()-->Print tree in sorted order
errors
Throws underflowException as warranted
*/
template<typename Comparable>
class BinarySearchTree
{
public:
BinarySearchTree() :root{ nullptr }
{}
/*
Copy constructor
*/
BinarySearchTree(const BinarySearchTree&rhs) :root{ nullptr }
{
root = clone(rhs.root);
}
//Move constructor
BinarySearchTree(BinarySearchTree&&rhs) :root{ rhs.root }
{
rhs.root = nullptr;
}
//Destructor for the tree
~BinarySearchTree()
{
makeEmpty();
}
//Copy assignment
BinarySearchTree&operator=(const BinarySearchTree&rhs)
{
BinarySearchTree copy = rhs;
swap(*this, copy);
return *this;
}
//Move assignment
BinarySearchTree&operator=(BinarySearchTree&&rhs)
{
swap(root, rhs.root);
return *this;
}
/*
Find the smallest item in the tree.
Throw underflowException if empty.
*/
const Comparable&findMin()const
{
if (isEmpty())
throw UnderflowException{};
return findMin(root)->element;
}
/*
Find the largest item in the tree.
Throw underflowException if empty.
*/
const Comparable&findMax()const
{
if (isEmpty())
throw UnderflowException{};
return findMax(root)->element;
}
//Returns true if x is found in the tree.
bool contains(const Comparable&x)const
{
return contains(x, root);
}
/*
Test if the tree is logically empty.
Return true if empty, false otherwise.
*/
bool isEmpty()const
{
return root == nullptr;
}
//Print the tree contents in sorted order.
void printTree(ostream&out = cout)const
{
if (isEmpty())
out << "Empty tree" << endl;
else
printTree(root, out);
}
//Make the tree logically empty.
void makeEmpty()
{
makeEmpty(root);
}
//Insert x into the tree; duplicates are ignored.
void insert(const Comparable&x)
{
insert(x, root);
}
//Insert x into the tree; Duplicates are ignored.
void insert(Comparable&&x)
{
insert(move(x), root);
}
//Remove x from the tree. Nothing is done if x is not found.
void remove(const Comparable&x)
{
remove(x, root);
}
private:
struct BinaryNode
{
Comparable element;
BinaryNode *left;
BinaryNode *right;
BinaryNode(const Comparable&theElement, BinaryNode *lt, BinaryNode *rt) :element{ theElement },
left{ lt }, right{ rt } {}
BinaryNode(Comparable&&theElement, BinaryNode *lt, BinaryNode *rt) :element{ std::move(theElement) },
left{ std::move(lt) }, right{ rt } {}
};
BinaryNode *root;
/*
Internal method to insert into a subtree.
x is the item to insert.
t is the node that roots the subtree.
Set the new root of the subtree.
*/
void insert(const Comparable&x, BinaryNode*&t)
{
if (t == nullptr)
t = new BinaryNode{ x,nullptr,nullptr };
else if (x < t->element)
insert(x, t->left);
else if (x > t->element)
insert(x, t->right);
else
;//Duplicate: do nothing
}
/*
Internal method to insert into a subtree.
x is the item to insert.
t is the node that root the subtree.
Set the new root of the subtree.
*/
void insert(Comparable&&x, BinaryNode*&t)
{
if (t == nullptr)
t = new BinaryNode{ move(x),nullptr,nullptr };
else if (x < t->element)
insert(move(x), t->left);
else if (x > t->element)
insert(move(x), t->right);
else
;//Duplicate; do nothing;
}
/*
Internal method to remove from a subtree.
x is the item to remove.
t is the node that roots the subtree.
Set the new root of the subtree.
*/
void remove(const Comparable&x, BinaryNode*&t)
{
if (t == nullptr)
return;
if (x < t->element)
remove(x, t->left);
else if (x > t->element)
remove(x, t->right);
else if (t->left != nullptr&&t->right != nullptr)//Two children
{
t->element = findMin(t->right)->element;
remove(t->element, t->right);
}
else
{
BinaryNode *oldNode = t;
t = (t->left != nullptr) ? t->left : t->right;
delete oldNode;
}
}
/*
Internal method to find the smallest item in a subtree t.
Return node containing the smallest item.
*/
BinaryNode*findMin(BinaryNode*t)const
{
if (t == nullptr)
return nullptr;
if (t->left == nullptr)
return t;
return findMin(t->left);
}
/*
Internal method to find the largest item in a subtree t.
Return node containing the largest item.
*/
BinaryNode*findMax(BinaryNode*t)const
{
if (t != nullptr)
while (t->right != nullptr)
t = t->right;
return t;
}
/*
Internal method to test if an item is in a subtree.
x is item to search for.
t is the node that roots the subtree.
*/
bool contains(const Comparable &x, BinaryNode*t)const
{
if (t == nullptr)
return false;
else if (x < t->element)
return contains(x, t->left);
else if (x > t->element)
return contains(x, t->right);
else
return true;
}
/*
Nonrecursive version
*/
/*
bool contains(const Comparable&x, BinaryNode*t)const
{
while (t != nullptr)
if (x < t->element)
t = t->left;
else if (t->element < x)
t = t->right;
else
return true;
return false;
}
*/
/*
Internal method to make subtree empty
*/
void makeEmpty(BinaryNode*&t)
{
if (t != nullptr)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = nullptr;
}
/*
Internal method to print a subtree rooted at t in sorted order.
*/
void printTree(BinaryNode*t, ostream&out)const
{
if (t != nullptr)
{
printTree(t->left, out);
out << t->element << endl;
printTree(t->right, out);
}
}
//Internal method to clone subtree.
BinaryNode*clone(BinaryNode*t)const
{
if (t == nullptr)
return nullptr;
else
return new BinaryNode{ t->element,clone(t->left),clone(t->right) };
}
};
BinarySearchTree
最新推荐文章于 2024-04-28 13:01:08 发布