BST终极版,已通过OJ的检验,应该没问题。
// Binary tree node implementation
#include<iostream>
using namespace std;
template <typename E>
class BSTNode
{
private:
E it; // The node's value;
BSTNode* lc; // Pointer to left child
BSTNode* rc; // Pointer to right child
public:
// Two constructors -- with and without initial values
BSTNode(){ lc = rc = NULL; }
BSTNode(E e, BSTNode* l = NULL, BSTNode* r = NULL){
it = e; lc = l; rc = r;
}
~BSTNode(){} // Destructor
// Functions to set and return the value
E& element(){ return it; }
void setElement(const E& e){ it = e; }
// Functions to set and return the children
inline BSTNode* left() const { return lc; }
void setLeft(BSTNode<E>* b){ lc = (BSTNode*)b; }
inline BSTNode* right() const { return rc; }
void setRight(BSTNode<E>* b){ rc = (BSTNode*)b; }
// Return true if it is a leaf, false otherwise
bool isLeaf(){ return lc == NULL && rc == NULL; }
};
// Binary Search Tree implementation
template <typename E>
class BST{
protected:
BSTNode<E>* root; // Root of the BST
int nodecount; // Number of nodes in the BST
// Private helper functions
void clearhelp(BSTNode<E>*);
BSTNode<E>* inserthelp(BSTNode<E>*, const E&);
BSTNode<E>* deletemin(BSTNode<E>*);
BSTNode<E>* getmin(BSTNode<E>*);
BSTNode<E>* removehelp(BSTNode<E>*, const E&);
bool findhelp(BSTNode<E>*, const E&) const;
void printhelp(BSTNode<E>*, int) const;
void find_ith(BSTNode<E>* root, int& count, int dest, E& res) const;
BSTNode<E>* delete_less_than(BSTNode<E>* root, const E& key);
BSTNode<E>* delete_greater_than(BSTNode<E>* root, const E& key);
BSTNode<E>* delete_interval(BSTNode<E>* root, const E& lkey, const E& hkey);
int count(BSTNode<E>* root){
if (root == NULL) return 0;
else return 1 + count(root->left()) + count(root->right());
}
public:
BST(){ root = NULL; nodecount = 0; }
~BST(){ clearhelp(root); }
void clear(){ // Reinitialize tree
clearhelp(root); root = NULL; nodecount = 0;
}
// Insert a record into the tree
void insert(const E& e){
root = inserthelp(root, e);
nodecount++;
}
// Remove a record from the tree
void remove(const E& e){
if (findhelp(root, e)){
root = removehelp(root, e);
nodecount--;
}
}
// Remove and return the root node
E removeAny(){
assert(root != NULL);
E tmp = root->element();
root = removehelp(root, tmp);
nodecount--;
return tmp;
}
bool find(const E& e) const {
return findhelp(root, e);
}
// Return the number of nodes in the tree
int size(){ return nodecount; }
void print() const { // Print the contents of the BST
if (root == NULL) cout << "The BST is empty." << endl;
else printhelp(root, 0);
}
E find_ith(int th) const {
E tmp;
int count = 0;
find_ith(root, count, th, tmp);
return tmp;
}
void delete_less_than(const E& key){
root = delete_less_than(root, key);
}
void delete_greater_than(const E& key){
root = delete_greater_than(root, key);
}
void delete_interval(const E& lkey, const E& hkey){
root = delete_interval(root, lkey, hkey);
}
int count(){
return count(root);
}
};
template <typename E>
bool BST<E>::findhelp(BSTNode<E>* root, const E& e) const {
if (root == NULL) return false;
if (e < root->element()) return findhelp(root->left(), e);
else if (e > root->element()) return findhelp(root->right(), e);
else return true;
}
template <typename E>
BSTNode<E>* BST<E>::inserthelp(BSTNode<E>* root, const E& e){
if (root == NULL) return new BSTNode<E>(e);
if (e < root->element()) root->setLeft(inserthelp(root->left(), e));
else root->setRight(inserthelp(root->right(), e));
return root;
}
template <typename E>
BSTNode<E>* BST<E>::deletemin(BSTNode<E>* root){
if (root->left() == NULL) return root->right();
else{
root->setLeft(deletemin(root->left()));
return root;
}
}
template <typename E>
BSTNode<E>* BST<E>::getmin(BSTNode<E>* root){
if (root->left() == NULL) return root;
else return getmin(root->left());
}
template <typename E>
BSTNode<E>* BST<E>::removehelp(BSTNode<E>* root, const E& e){
if (root == NULL) return NULL;
else if (e < root->element()) root->setLeft(removehelp(root->left(), e));
else if (e > root->element()) root->setRight(removehelp(root->right(), e));
else {
BSTNode<E>* tmp = root;
if (root->left() == NULL){
root = root->right();
delete tmp;
}
else if (root->right() == NULL){
root = root->left();
delete tmp;
}
else {
BSTNode<E>* tmp = getmin(root->right());
root->setElement(tmp->element());
root->setRight(deletemin(root->right()));
delete tmp;
}
}
return root;
}
template <typename E>
void BST<E>::clearhelp(BSTNode<E>* root){
if (root == NULL) return;
clearhelp(root->left());
clearhelp(root->right());
delete root;
}
template <typename E>
void BST<E>::printhelp(BSTNode<E>* root, int level) const {
if (root == NULL) return;
printhelp(root->left(), level + 1);
for (int i = 0; i <= level; i++) cout << " ";
cout << "Level " << level << ": " << root->element() << endl;
printhelp(root->right(), level + 1);
}
template <typename E>
void BST<E>::find_ith(BSTNode<E>* root, int& count, int dest, E& res) const {
if (root == NULL) return;
if (count == dest) return;
find_ith(root->left(), count, dest, res);
if (count == dest) return;
count++;
if (count == dest) res = root->element();
else find_ith(root->right(), count, dest, res);
}
template <typename E>
BSTNode<E>* BST<E>::delete_less_than(BSTNode<E>* root, const E& key){
if (root == NULL) return NULL;
if (root->element() < key){
clearhelp(root->left());
BSTNode<E>* tmp = root;
root = delete_less_than(root->right(), key);
delete tmp;
return root;
}
else {
root->setLeft(delete_less_than(root->left(), key));
return root;
}
}
template <typename E>
BSTNode<E>* BST<E>::delete_greater_than(BSTNode<E>* root, const E& key){
if (root == NULL) return NULL;
if (root->element() > key){
clearhelp(root->right());
BSTNode<E>* tmp = root;
root = delete_greater_than(root->left(), key);
delete tmp;
return root;
}
else {
root->setRight(delete_greater_than(root->right(), key));
return root;
}
}
template <typename E>
BSTNode<E>* BST<E>::delete_interval(BSTNode<E>* root, const E& lkey, const E& hkey){
if (root == NULL) return NULL;
if (root->element() >= hkey) {
root->setLeft(delete_interval(root->left(), lkey, hkey));
return root;
}
else if (root->element() <= lkey){
root->setRight(delete_interval(root->right(), lkey, hkey));
return root;
}
else {
BSTNode<E>* tmp = root;
BSTNode<E>* tmp1 = delete_interval(root->left(), lkey, hkey);
BSTNode<E>* tmp2 = delete_interval(root->right(), lkey, hkey);
delete tmp;
if (tmp1 == NULL && tmp2 == NULL) return NULL;
else if (tmp1 == NULL && tmp2 != NULL) return tmp2;
else if (tmp1 != NULL && tmp2 == NULL) return tmp1;
else {
BSTNode<E>* right_min = tmp2;
while (right_min->left() != NULL) right_min = right_min->left();
BSTNode<E>* new_root = new BSTNode<E>(right_min->element());
tmp2 = removehelp(tmp2, new_root->element());
new_root->setLeft(tmp1);
new_root->setRight(tmp2);
return new_root;
}
}
}
相比起平衡树,BST的实现还是比较简单的,主要是运用递归的方法,实现二分查找,插入和删除(查找和插入也可以不用递归,用简单的循环实现)。若将BSTNode作为BST的内嵌类,实现起来更简单,代码更加简洁。