BST

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的内嵌类,实现起来更简单,代码更加简洁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值