二分搜索树完整实现

包括二分搜索树的创建,插入,删除,前序、中序、后序、广度以及深度的递归和递归算法,获取二叉树最小节点,最大节点,获取当前节点的后序或者前序节点,对二叉树的搜索判定:

template<typename T>
class treenode{
public:
T ele;
treenode<T>*left;
treenode<T>*right;
treenode(){left=NULL;
right=NULL;}
treenode(T ele){
	this->ele=ele;
left=NULL;
right=NULL;}
};

template<typename T>
class bitree{
private:treenode<T>*root;
		int size;
         void inorder(treenode<T>*root);
		 void preorder(treenode<T>*root);
		 void postorder(treenode<T>*root);
public:
	bitree(){root=NULL;size=0;}
	bitree(T ele[],int size);
	bool insert(T ele);
    void inorder();
void preorder();
void postorder();

// 获取二叉树的最小关键字节点
treenode<T>*getmin(treenode<T>*root){
	treenode<T>*pa=NULL;
if (root==NULL)return NULL;
else{
	while(root!=NULL){pa=root;
		root=root->left;}
return pa;}
}
// 获取二叉树的最大关键字节点
treenode<T>*getmax(treenode<T>*root1){
	treenode<T>*pa=NULL;
if (root1==NULL)return NULL;
else{
	while(root1!=NULL){pa=root1;
		root1=root1->right;}
return pa;}
}
 // 获取给定节点在中序遍历下的后续节点
treenode<T>*getafter(treenode<T>*p){
if(p==NULL) return NULL;
else{// 分两种情况考虑,此节点是否有右子树
      // 当这个节点有右子树的情况下,那么右子树的最小关键字节点就是这个节点的后续节点
	if(p->right!=NULL) return getmin(p->right);
	 // 当这个节点没有右子树的情况下,
  // 如果这个节点的父节点的左子树 与 这个节点相同的话,那么就说明这个父节点就是后续节点了
treenode<T>*parent=getparent(p);
//while(parent!=NULL&&parent->right==p){
//p=parent;
//parent=getparent(parent);}
return parent;
}}
 // 获取给定节点在中序遍历下的前趋结点
treenode<T>*getbefore(treenode<T>*p){
if(p==NULL) return NULL;
else{// 分两种情况考虑,此节点是否有左子树
      // 当这个节点有右子树的情况下,那么右子树的最小关键字节点就是这个节点的后续节点
	if(p->left!=NULL) return getmax(p->left);
	 // 当这个节点没有左子树的情况下,
  // 那么就说明这个父节点就是后续节点了
treenode<T>*parent=getparent(p);
while(parent!=NULL&&parent->right==p){
p=parent;
parent=getparent(parent);}
return parent;
}}
bool search(T ele,treenode<T>*root){
	if(root==NULL) return false;
else{while(root!=NULL){
   if(ele==root->ele) return true;
   else if(ele<root->ele) 
	return search(ele,root->left);
   else return search(ele,root->right);}
  return false;}}
treenode<T>* search_node(T ele){return search_node(ele,root);}
treenode<T>* search_node(T ele,treenode<T>*root){
	int f=0;treenode<T>*p=root;
	if(root==NULL) return root;
else{while(root!=NULL){
	if(ele==root->ele) {f=1;return root;}
   else if(ele<root->ele) 
	return search_node(ele,root->left);
   else return search_node(ele,root->right);}
if(f==0)return NULL;}}
treenode<T>* getparent(treenode<T>*current){
	treenode<T>*pa=NULL;
treenode<T>*p=current;
if(p==root) return NULL;
treenode<T>*pp=root;
while(pp!=current){
	if(current->ele<pp->ele){
pa=pp;
pp=pp->left;
	}
	else if(current->ele>pp->ele){pa=pp;pp=pp->right;}
	else break;}
return pa;}

bool search(T ele){
	return search(ele,root); }//搜索指定元素

void deleteele(treenode<T>*current){
treenode<T>*pa=getparent(current);
treenode<T>*p=current;
// 第一种情况:删除没有子节点的节点
if(root==NULL) throw runtime_error("empty");
if(p->left==NULL&&p->right==NULL){
   if(p==root) root=NULL;
   else if(p==pa->left) pa->left=NULL;
   else pa->right=NULL;}


//删除的节点只含右节点
if(p->left==NULL&&p->right!=NULL){
	if(p==root) root=root->right;
	else if(p==pa->left) pa->left=p->right;
	else pa->right=p->right;}
//如果要删除的节点只有左节点
if(p->left!=NULL&&p->right==NULL){
	if(p==root) root=root->left;
	else if(p==pa->left) pa->left=p->left;
	else pa->right=p->left;}

 // 如果要删除的节点有两个子节点,即左右子节点都非空
// 方法是用要删除的节点的后续节点代替要删除的节点,并且删除后续节点(删除后续节点的时候同样的递归操作)
// 其实,这里要用到的最多也就会发生两次,即后续节点不会再继续递归的删除下一个后续节点了
// 因为,要删除的节点的后续节点肯定是 要删除的那个节点的右子树的最小关键字,而这个最小关键字肯定不会有左节点
 // 所以,在删除后续节点的时候肯定不会用到( 两个节点都非空的判断 ),如有有子节点,肯定就是有一个右节点。

if(p->left!=NULL&&p->right!=NULL){
  treenode<T>*parent=p;
  treenode<T>*child=p->left;
  while(child->right!=NULL)
  {
   parent=child;
   child=child->right;
  }
  p->ele=child->ele;
  if(parent->left==child)
   parent->left=child->left;
  else
   parent->right=child->left;
  delete(child);
}
}
void deleteele(T ele){
	treenode<T>*p=search_node(ele);
	if(p==NULL) cout<<"no the value:"<<endl;
   else deleteele(p);
}
void prt(treenode<T>*left,treenode<T>*right){
	if(left==NULL&&right==NULL)return ;
	else   if(left==NULL&&right!=NULL) cout<<right->ele<<" ";
	else if(right==NULL&&left!=NULL) cout<<left->ele<<" ";
	else{	cout<<left->ele<<" ";
	cout<<right->ele<<" ";
	}}
//深度优先遍历
void depthFirstSearch(treenode<T>*root){
    stack<treenode<T> *> nodeStack;  //使用C++的STL标准模板库
    nodeStack.push(root);
    treenode<T> *node;
    while(!nodeStack.empty()){
        node = nodeStack.top();
		cout<<node->ele<<" ";  //遍历根结点
        nodeStack.pop();
		if(node->right){
            nodeStack.push(node->right);  //先将右子树压栈
        }
		if(node->left){
            nodeStack.push(node->left);  //再将左子树压栈
        }
    }
}
void depthFirstSearch(){
depthFirstSearch(root);}
void breadthFirstSearch(treenode<T>* root){
    queue<treenode<T> *> nodeQueue;  //使用C++的STL标准模板库
	nodeQueue.push(root);
    treenode<T> *node;
    while(!nodeQueue.empty()){
        node = nodeQueue.front();
        nodeQueue.pop();
		cout<<node->ele<<" ";
        if(node->left){
            nodeQueue.push(node->left);  //先将左子树入队
        }
        if(node->right){
            nodeQueue.push(node->right);  //再将右子树入队
        }
    }
}
void breadthfirst()//广度优先遍历
{breadthFirstSearch(root);
}
treenode<T>*getroot(){return root;}
};

template<typename T>
bitree<T>::bitree(T ele[],int size){
root=new treenode<T>(ele[0]);
this->size=size;;
for(int i=0;i<size;i++)
  insert(ele[i]);}
template<typename T>
bool bitree<T>::insert(T ele){
if(root==NULL) root=new treenode<T>(ele);
else{
treenode<T>*parent=NULL;
treenode<T>*p=root;
while(p!=NULL){
	if(ele<p->ele){parent=p;
	p=p->left;}//新元素小于父节点,则做父节点左孩纸
	else if(ele>p->ele){parent=p;p=p->right;}//新元素大于父节点,则做父节点右边孩纸
	else return false;}
	if(ele<parent->ele)parent->left=new treenode<T>(ele);
	else parent->right=new treenode<T>(ele);
}
size++;
return true;}

template<typename T>
void bitree<T>::inorder(){
inorder(root);}
template<typename T>
void bitree<T>::inorder(treenode<T>*root){
	if(root==NULL)return;
	/*inorder(root->left);
	cout<<root->ele<<" ";
	inorder(root->right);*/
	stack<treenode<T>*> heapin;
	while(root!=NULL||!heapin.empty()){
		if(root!=NULL){heapin.push(root);
		root=root->left;}
		else{
			root=heapin.top();
			heapin.pop();
			cout<<root->ele<<" ";
			root=root->right;}
		
}
}//中序遍历,递归
template<typename T>
void bitree<T>::preorder(){
preorder(root);}
template<typename T>
void bitree<T>::preorder(treenode<T>*root){
	if(root==NULL)return;
	/*else{
	cout<<root->ele<<" ";
	preorder(root->left);
	preorder(root->right);}*///注释处为递归算法
	stack<treenode<T>* >ss;
	while(root!=NULL||!ss.empty()){
		if(root!=NULL){
			cout<<root->ele<<" ";
			ss.push(root);
			root=root->left;}
		else{
			root=ss.top();
			ss.pop();
			root=root->right;}}}//前序遍历
template<typename T>
void bitree<T>::postorder(){
postorder(root);}
template<typename T>
void bitree<T>::postorder(treenode<T>*root){
	if(root==NULL) {return;}
/*else{postorder(root->left);
postorder(root->right);
cout<<root->ele<<" ";
}*/
treenode<T>*p=NULL;
stack<treenode<T>*>s;
treenode<T>*cu;
s.push(root);
while(!s.empty()){
	cu=s.top();
	if((cu->left==NULL&&cu->right==NULL)||
		(p!=NULL&&(p==cu->left||p==cu->right)))
        {
			cout<<cu->ele<<" ";  //如果当前结点没有孩子结点或者孩子节点都已被访问过 
              s.pop();
            p=cu; 
        }
else
        {
			if(cu->right!=NULL)
				s.push(cu->right);
			if(cu->left!=NULL)    
				s.push(cu->left);
        }}
}//后序

你可能感兴趣的:(二分搜索树完整实现)