/************************************************************************* > File Name: BinarySearchTree.h > Author:keson > Mail:[email protected] > Created Time: 2014年11月22日 星期六 21时11分46秒 ************************************************************************/ #ifndef _BINARYSEARCHTREE_H #define _BINARYSEARCHTREE_H #include"dsexceptions.h" #include<algorithm> using namespace std; //BinarySearchTree class // //CONSTRUCTOR: zero parameter // //***************PUBLIC OPERATIONS******************** //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 makeEmpty() -->Remove all items //void printTree() -->Print tree in sorted order //***************ERRORS******************************* template<typename Comparable> class BinarySearchTree { public: //constructor BinarySearchTree():root(nullptr) {} //copy constructor BinarySearchTree(const BinarySearchTree &rhs) { root=clone(rhs.root); } //move constructor BinarySearchTree(BinarySearchTree &&rhs); //Deconstructor ~BinarySearchTree() { makeEmpty(); } const Comparable& findMin() const { if(isEmpty()) throw UnderflowException{}; return findMin(root)->element; } const Comparable& findMax() const { if(isEmpty()) throw UnderflowException{}; return findMax(root)->element; } bool contains(const Comparable &x)const { return contains(x,root); } bool isEmpty() const { return root==nullptr; } void printTree(ostream &out=cout) const { if (isEmpty()) out<<"Empty tree"<<endl; else printTree(root,out); } void makeEmpty() { makeEmpty(root); } /** * Insert x into the tree ,duplicates are ignored. */ void insert(const Comparable &x) { insert(x,root); } void insert(Comparable &&x) { insert(std::move(x),root); } /** * Remove x from the tree.Nothing is done if x is not found */ void remove(const Comparable &x) { remove(x,root); } //copy assignment BinarySearchTree &operator=(const BinarySearchTree &rhs) { BinarySearchTree copy=rhs; std::swap(*this,copy); return *this; } //move assignment BinarySearchTree &operator=(BinarySearchTree &&rhs) { std::swap(root,rhs.root); return *this; } private: struct BinaryNode { Comparable element; BinaryNode *left; BinaryNode *right; //constructor BinaryNode(const Comparable &theElement,BinaryNode *lt,BinaryNode *rt) :element{theElement},left{lt},right{rt} {} //move constructor BinaryNode(Comparable &&theElement,BinaryNode *lt,BinaryNode *rt) :element{std::move(theElement)},left{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. * pass the reference,so can change the original node's * left and right node point to new node. */ 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(t->element<x) insert(x,t->right); else ; //duplicates;do nothing } void insert(Comparable &&x,BinaryNode * &t) { if(t==nullptr) t=new BinaryNode{std::move(x),nullptr,nullptr}; else if(x<t->element) insert(std::move(x),t->left); else if(t->element<x) insert(std::move(x),t->right); else ; //duplicates;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; //item not found;do nothing if(x<t->element) remove(x,t->left); else if(t->element<x) 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); //one child or leave } else //one child or leave { BinaryNode *oldNode=t; t=(t->left!=nullptr)? t->left:t->right; delete oldNode; } } //pass the value ,only the copy of the pointer /** * Internal method to find the smallest item in s subtree t. * return node containing the smallest item * Recursive implementation */ 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. * Nonrecursive implementation * pass value ,so t is just the copy of the pointer * we change don't just the original */ 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; //leave's left node and right node are nullptr else if(x<t->element) return contains(x,t->left); else if(t->element<x) return contains(x,t->right); else return true; //match } /** * Internal method to make subtree empty. */ void makeEmpty(BinaryNode * &t) { if(t!=nullptr) { makeEmpty(t->left); makeEmpty(t->right); delete t; } t=nullptr; } void printTree(BinaryNode *t,ostream &out) const { if(t!=nullptr) { printTree(t->left,out); out<<t->element; printTree(t->right,out); } } /** * Internal method to subtree. */ BinaryNode *clone(BinaryNode *t) const { if(t==nullptr) return nullptr; else return new BinaryNode{t->element,clone(t->left),clone(t->right)}; } }; #endif