• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

C++ 二叉搜索树 模板

OC/C/C++ 水墨上仙 1865次浏览

以前写的二叉搜索树,其中节点是类模板,可对任何实现了比较大小的数据的插入、查找及删除操作。
并使用Traits技术实现了使用迭代器对操作数据,移植性好,效率较高。使用请注明出处,谢谢。
来源:http://blog.csdn.net/guankle/article/details/8133945

#pragma once
#include <iostream>
#include <cstdlib>
#include <queue>
using namespace std;
template <class T> class STree;
template<class T, class Ref=T&, class Ptr=T*> class STree_iterator;
template<class T, class Ref=T&, class Ptr=T*> class STree_const_iterator;
///////////////////////////////////////////////////////////////////////////////////////
//search tree NODE
template <class T>
class TNode{
	friend class STree<T>;   //bound friend
	friend class STree_iterator<T>;
	friend class STree_const_iterator<T>;
protected:
	T data;
	TNode<T> *left, *right, *parent;
	void copy(const TNode<T> &rhs) {
		//if(rhs==NULL) {cout<<"error: no source"<<endl; return;}
		left=rhs.left;
		right=rhs.right;
		parent=rhs.parent;
		data=rhs.data;
	}
public:
	TNode() {left=NULL, right=NULL, parent=NULL;}
	TNode(const T &item, TNode<T> *lptr=NULL, TNode<T> *rptr=NULL, TNode<T> *pptr=NULL)
		 :data(item), left(lptr), right(rptr), parent(pptr) {}	
	
	TNode( const TNode<T> &rhs) { copy(rhs);	}
	TNode<T> &operator=(const TNode<T> &rhs) { copy(rhs); return *this;}
	~TNode() {}
};
///////////////////////////////////////////////////////////////////////////////////////
//binary search tree declaration
template <class T>
class STree {
	friend class STree_iterator<T>;
	friend class STree_const_iterator<T>;
protected:
	TNode<T> *root;
	int size;
	TNode<T> *GetNode(const T &item, TNode<T> *lptr, TNode<T> *rptr, TNode<T> *pptr);  //allocate storage for the current root node
	TNode<T> *copy(TNode<T> *rhs);
	void DelTree(TNode<T> *root);
	TNode<T> *findNode(const T& item) const;  //only the type of return value is different, it seems polymorphism must be sacrificed
public:
	typedef T value_type;
	typedef value_type* pointer;
	typedef STree_iterator<T, T&, T*> iterator;
	typedef STree_const_iterator<T, T&, T*> const_interator;	
	STree(void);
	STree(T *first, T *last);
	STree(const STree<T> &rhs);
	STree<T> &operator=(const STree<T> &rhs);	//support 
	 ~STree(void);
	iterator begin();//return the iterator of the node which should be firstly calls for
	iterator end();//return the last node in the tree
	int height(TNode<T> *cur) const;//calculate the height of the tree whose root is cur;
	iterator find(const T& item);//find element in the tree
	iterator insert(const T& item);//insert element in the tree
	bool erase(const T& item);//if item exist, erase it and return true
	void erase(iterator pos);/*select the minimum one (R) in the right sub tree to substitute the deleted node, 
									 connect the right subtree of R to its parent as the left sub tree 
									 connect the left subtree of the deleted node to R as the left subtree link the right 
									 subtree of the deleted node to R as its right sub tree, and the substitute the 
									 deleted node with R*/
	void erase(iterator first, iterator last);
	void LevelorderPrint();
	bool empty() const {return root==NULL;}
	int Size() const {return size;}
	TNode<T> *Root() {return root;}
};  //end of declaration of STree
///////////////////////////////////////////////////////////////////////////////////////
//binary search tree implementation
//construction and destruction 
template <class T>
STree<T>::STree(void){
	root=NULL;
	size=0;
}
template <class T> 
STree<T>::STree(T *first, T *last) {
	root=NULL;
	size=0;	
	while(first!=last) {
		insert(*first);
		++first;
	}
}
template <class T> 
STree<T>::STree(const STree<T> &rhs) {
	root=copy( rhs.Root() );
	size=rhs.Size();
}
template <class T> 
STree<T> &STree<T>::operator=(const STree<T> &rhs){
	if(this==rhs) return this;
	DelTree(root);
	root=copy(rhs.Root());
	size=rhs.Size();
	return this;
}
template <class T>
STree<T>::~STree(void){
	DelTree(root);
}
//private routines
template <class T>
TNode<T> *STree<T>::GetNode(const T &item, TNode<T> *lptr, TNode<T> *rptr, TNode<T> *pptr){
	TNode<T> *newnode=new TNode<T>(item, lptr, rptr, pptr);
	if(newnode==NULL) {cerr<<"allocate storage for new node failed!"<<endl; exit(0);}
			/*throw referenceError
				("allocate storage for new node failed!");*/
	return newnode;
}
template <class T>
TNode<T> *STree<T>::copy(TNode<T> *rhs){
	TNode<T> *lptr, *rptr, *newnode;
	if(rhs==NULL) return NULL;
	lptr=copy(rhs->left);
	rptr=copy(rhs->right);//recurisively copy
	newnode=GetNode(rhs->data, lptr, rptr, NULL);
	if(lptr!=NULL) lptr->parent=newnode;
	if(rptr!=NULL) rptr->parent=newnode;
	return newnode;//return the root of the current tree
}
template <class T>
void STree<T>::DelTree(TNode<T> *_root) {
	if(_root!=NULL){
		DelTree(_root->left);
		DelTree(_root->right);
		delete _root;
	}
}
template <class T>
TNode<T> *STree<T>::findNode(const T& item) const {
	TNode<T> *cur=root;
	while(cur!=NULL) {
		if(item==cur->data) return cur;
		else if(item<cur->data) cur=cur->left;
		else cur=cur->right;
	}
	return cur;
}
//interface 
template <class T>
int STree<T>::height(TNode<T> *cur) const {
	int r_depth, l_depth, depth;
	if(cur==NULL) depth=-1;
	else {
		r_depth=height(cur->right);
		l_depth=height(cur->left);
		depth=1+(r_depth>l_depth?r_depth:l_depth);
	}
	return depth;
}
template <class T>
typename STree<T>::iterator STree<T>::find(const T& item){
	TNode<T> *cur;
	cur=findNode(item);
	if(cur!=NULL) return STree<T>::iterator(cur, this);
	else return this->end();
}
template <class T>
typename STree<T>::iterator STree<T>::insert(const T& item) {
	TNode<T> *cur=root, *par=NULL, *newnode;
	while(cur!=NULL) {
		par=cur;
		if(item==cur->data) return STree<T>::iterator(cur, this);
		else if(item<cur->data) cur=cur->left;
		else cur=cur->right;
	}
	newnode=GetNode(item, NULL, NULL, par);
	if(par==NULL) root=newnode;
	else if(item<par->data) par->left=newnode;
	else par->right=newnode;
	++size;
	return STree<T>::iterator(newnode, this);
}
template <class T>
bool STree<T>::erase(const T& item) {
	STree<T>::iterator pos=find(item);
	if( pos!=end() ) erase(pos);
	return pos!= end();
}
template <class T>
void STree<T>::erase(typename STree<T>::iterator pos) {
	TNode<T> *del=pos.pn;
	if(del==NULL) return;
	TNode<T> *par=del->parent, *subs;
	if(del->left==NULL || del->right==NULL) {
		if(del->left==NULL) subs=del->right;
		else subs=del->left;
		if(subs != NULL) subs->parent=par;		
	}
	else {		
		subs=del->right;
		TNode<T> *temp=del;
		while(subs->left!=NULL) {
			temp=subs;
			subs=subs->left;
		}
		if(temp==del) {
			subs->left=del->left;
			subs->parent=par;
			subs->left->parent=subs;
		}
		else {
			temp->left=subs->right;	//reconstructe left tree of upstream node
			if(subs->right!=NULL) subs->right->parent=temp;
		
			subs->left=del->left;//reconstructe left tree of substitute
			subs->left->parent=subs;
			subs->right=del->right;//reconstructe right tree of substitute
			subs->right->parent=subs;
			subs->parent=par;//modify parent pointer of substitute
		}
	}
	if(par==NULL) root=subs;	
	else if(par->left==del) par->left=subs;
	else par->right=subs;
	delete del;
	--size;
}
template <class T>
void STree<T>::erase(typename STree<T>::iterator first, typename STree<T>::iterator last){
	STree<T>::iterator iter=first;
	while(iter!=last) {
		erase(iter);
		++iter;
	}
}
template <class T>
void STree<T>::LevelorderPrint() {
	queue< TNode<T> > parQ;
	queue< TNode<T> > chdQ;
	TNode<T> *cur=new TNode<T>;
	parQ.push(*root);
	while(!parQ.empty()) {
		do{
			*cur=parQ.front();
			parQ.pop();
			cout<<cur->data<<ends;
			if(cur->left!=NULL) chdQ.push(*(cur->left) );
			if(cur->right!=NULL) chdQ.push(*(cur->right) );
		}	while(!parQ.empty());
		cout<<endl;
		parQ=chdQ;
		queue< TNode<T> > empty;
		swap(chdQ, empty);
	}
	delete cur;
	cur=NULL;
}
//iterators
template <class T>
typename STree<T>::iterator STree<T>::begin(){
	TNode<T> *cur=root;
	if(cur!=NULL) 
		while(cur->left!=NULL)
			cur=cur->left;
	return STree<T>::iterator(cur, this);//this will point to the tree who call the function
}
template <class T>
typename STree<T>::iterator STree<T>::end(){//a null pointer will be returned, represent the last node
	return STree<T>::iterator(NULL, this);
}
///////////////////////////////////////////////////////////////////////////////////////
//binary search tree iterators
template<class T, class Ref, class Ptr>
class STree_iterator {//nested iterator declaration
		friend class STree<T>;
	public:
		typedef STree_iterator<T, T&, T*> iterator;
		typedef STree_iterator<T, Ref, Ptr> self;
		typedef std::bidirectional_iterator_tag iterator_category; 
		typedef T value_type;
		typedef Ref reference;
		typedef Ptr pointer;			
		typedef ptrdiff_t difference_type;		
	public:
		//constructors
		STree_iterator(){
			pn=NULL;
			tree=NULL;
		}
		STree_iterator(const STree_iterator &rhs) {//copy construction
			pn=rhs.pn;
			tree=rhs.tree;
		}
		//operators
		bool operator==(const STree_iterator &rhs) const {return pn == rhs.pn;}
		bool operator!=(const STree_iterator &rhs) const {return pn != rhs.pn;}
		reference operator*() const{
			if(pn==NULL) {cerr<<"allocate storage for new node failed!"<<endl; exit(0);}
				/*throw referenceError
					("allocate storage for new node failed!");*/
			return pn->data;
		}
		pointer operator->() const { return &( operator*() ); }
		self &operator++() { //move to the next node following inorder traversal
			TNode<T> *p;
			if(pn==NULL) {//pn point to the end, next should be the first one in the tree
				pn=tree->root;
				if(pn==NULL) { cerr<<"move on a empty tree!"<<endl; exit(0);}
					/*throw referenceError
						("allocate storage for new node failed!");*/
				while(pn->left!=NULL) pn=pn->left;
			}
			else if(pn->right != NULL) {//return the last node of the right subtree
				pn=pn->right;
				while(pn->left!=NULL) pn=pn->left;
			}
			else {//left subtree have been traversed and no right subtree, move to the parent
				p=pn->parent;
				while(p!=NULL && pn==p->right) {
					pn=p;
					p=p->parent;
				}
				pn=p;
			}
			return *this;//prefix, return current iterator (++iter)
		}
		self operator++(int) {//suffix iter++
			self temp(pn, tree);
			++(*this);//invoke ++iter;
			return temp;//return a object but the reference
		}
		self &operator--() { //move to the previous node following inorder traversal
			TNode<T> *p;
			if(pn==NULL) {//pn point to the end, next should be the last(not null) one in the tree
				pn=tree->root;
				if(pn==NULL) {cerr<<"move on a empty tree!"<<endl; exit(0);}
					/*throw referenceError
						("allocate storage for new node failed!");*/
				while(pn->right!=NULL) pn=pn->right;
			}
			else if(pn->left != NULL) {//return the last node of the left subtree
				pn=pn->left;
				while(pn->right!=NULL) pn=pn->right;
			}
			else {//left subtree have been traversed and no left subtree, move to the parent
				p=pn->parent;
				while(p!=NULL && pn==p->left) {
					pn=p;
					p=p->parent;
				}
				pn=p;
			}
			return *this;
		}
		self operator--(int) {
			self temp(pn, tree);
			--(*this);//invoke --iter;
			return temp;//return a object but the reference
		} 
	private:
		TNode<T> *pn;
		STree<T> *tree;
		STree_iterator(TNode<T> *p, STree<T> *t):pn(p), tree(t) {}
};
template<class T, class Ref, class Ptr>
class STree_const_iterator{
		friend class STree<T>;
	public:
		typedef STree_const_iterator<T, T&, T*> iterator;
		typedef STree_const_iterator<T, Ref, Ptr> self;
		typedef std::bidirectional_iterator_tag iterator_category; 
		typedef T value_type;
		typedef Ref reference;
		typedef Ptr pointer;			
		typedef ptrdiff_t difference_type;
	public:
		STree_const_iterator(){
			pn=NULL;
			tree=NULL;
		}
		STree_const_iterator(const STree_const_iterator &rhs){//copy construction
			pn=rhs.pn;
			tree=rhs.tree;
		}
		STree_const_iterator(const iterator &rhs){//copy construction
			pn=rhs.pn;
			tree=rhs.tree;
		}
		bool operator==(const STree_const_iterator &rhs) const {return pn == rhs.pn;}
		bool operator!=(const STree_const_iterator &rhs) const {return pn != rhs.pn;}
		const T &operator*() const {
			if(pn==NULL) { cerr<<"STree STree_const_iterator operator*(): NULL reference"<<endl; exit(0); }
				/*throw referenceError 
					("STree STree_const_iterator operator*(): NULL reference");*/
			return pn->data;
		}
		const pointer operator->() const { return &( operator*() ); }
		STree_const_iterator &operator++() { //move to the next node following inorder traversal
			TNode<T> *p;
			if(pn==NULL) {//pn point to the end, next should be the first one in the tree
				pn=tree->root;
				if(pn==NULL) { cerr<<"STree STree_const_iterator operator++(): tree empty"<<endl; exit(0); }
					/*throw underflowError
						("STree STree_const_iterator operator++(): tree empty");*/
				while(pn->left!=NULL) pn=pn->left;
			}
			else if(pn->right != NULL) {//return the last node of the right subtree
				pn=pn->right;
				while(pn->left!=NULL) pn=pn->left;
			}
			else {//left subtree have been traversed and no right subtree, move to the parent
				p=pn->parent;
				while(p!=NULL && pn==p->right) {
					pn=p;
					p=p->parent;
				}
				pn=p;
			}
			return *this;//prefix, return current iterator (++iter)
		}
		STree_const_iterator operator++(int) {//suffix iter++
			STree<T>::STree_const_iterator temp(pn, tree);
			++(*this);//invoke ++iter;
			return temp;//return a object but the reference
		}
		STree_const_iterator &operator--() { //move to the previous node following inorder traversal
			TNode<T> *p;
			if(pn==NULL) {//pn point to the end, next should be the last(not null) one in the tree
				pn=tree->root;
				if(pn==NULL)
					throw underflowError
					("STree STree_const_iterator operator++(): tree empty");
				while(pn->right!=NULL) pn=pn->right;
			}
			else if(pn->left != NULL) {//return the last node of the left subtree
				pn=pn->left;
				while(pn->right!=NULL) pn=pn->right;
			}
			else {//left subtree have been traversed and no left subtree, move to the parent
				p=pn->parent;
				while(p!=NULL && pn==p->left) {
					pn=p;
					p=p->parent;
				}
				pn=p;
			}
			return *this;
		}
		STree_const_iterator operator--(int) {
			STree_const_iterator temp(pn, tree);
			--(*this);//invoke --iter;
			return temp;//return a object but the reference
		}
	private:
		const TNode<T> *pn;
		const STree<T> *tree;
		STree_const_iterator(const TNode<T> *p, const STree<T> *t):pn(p), tree(t) {}
	};


喜欢 (0)
加载中……