动态查找表--二叉排序树的实现

       动态查找表的特点是表结构本身是在查找过程中动态生成的。二叉排序树的定义是:或者是一颗空树,或者是具有下列性质的二叉树:(1)若它的左子树不空,则左子树上所有结点的值均小于它的根节点的值;(2)若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3)它的左右子树也分别是二叉排序树。可以用二叉链表作为二叉排序树的存储结构。程序实现如下:

/*****************************静态查找表的建立及顺序查找操作******************************/
//by vipper.zhang 2011.7.11 如果有什么问题或者可以改进的建议,请发邮件至vipper.zhang@gmail.com 
//O(∩_∩)0

#include <iostream>

using namespace std;
typedef int KeyType;

//二叉链表存储二叉查找树结点
typedef struct BSTNode{
	KeyType key;
    BSTNode *lchild,*rchild;
}*BSTree;

//查找元素
bool SearchBST(BSTree bst,KeyType key,BSTree f,BSTree &p)   //f为bst双亲,p返回等于key的结点
{
   if(!bst) 
   {
	   p=f;
	   return false;
   }
   else if((bst->key)==key) 
   {
	   p=bst;
	   return true;
   }
   else if((bst->key) >key)  return SearchBST(bst->lchild,key,bst,p);
   else if((bst->key) <key)  return SearchBST(bst->rchild ,key,bst,p);
}


//插入元素
bool InsertBST(BSTree &bst,KeyType key)
{
	BSTree p=new BSTNode;
    if(!SearchBST(bst,key,NULL,p))
	{

		BSTree s=new BSTNode();
		s->key =key;
		s->lchild =s->rchild =NULL;
		if(!p) bst=s;
		else if(key< p->key)
			p->lchild=s;
		else if(key>p->key)
			p->rchild=s;
		return true;
	} 
	return false;
}

//创建二叉排序树
void CreateBST(BSTree &bst)
{ 
	
   KeyType key;
   while (cin>>key)
   {
	   if(key==-1)
		   break;
	   else
		   InsertBST(bst,key);
   }
}

BSTree GetFather(BSTree bst,BSTree p)
{
	if(bst==NULL||p==bst)
		return NULL;
	else if(bst->lchild ==p||bst->rchild==p)
		return bst;
	else if(bst->key <p->key)
	{
      GetFather(bst->rchild ,p);
	}
	else if(bst->key >p->key )
		GetFather(bst->lchild ,p);
}

//删除结点
bool DeleteBST(BSTree &bst,KeyType key)
{
	BSTree p,q,s,f;
	p=bst;
	if(!bst)
	{
		cout<<"bst tree does not exit"<<endl;
		return false;
	}
	do                //找到关键字所在结点p
	{
	if(p->key==key)
	{    
        break;
	}
	else if(bst->key >key)
		p=p->lchild ;
	else if(bst->key <key)
		p=p->rchild;
	}while(p);
    
	if(p==NULL)
	{
        cout<<"no such element "<<endl;
		return false;
	}
	else{
		f=GetFather(bst,p);              //找到p结点的父亲结点

		
		if(!p->lchild&&(!p->rchild)&&f!=NULL)    //p是叶子结点, 且不是根结点
		{
			if(f->lchild ==p)
			{
				delete p;
				f->lchild =NULL;
			}
			else
			{
				delete p;
				f->rchild =NULL;
			}
			return true;
		}
		if(!p->lchild && !p->rchild && f==NULL)   //p是叶子结点, 且是根结点
		{
			bst=NULL;
            delete p;

            return true;
		}
			
		if(!p->lchild&&f!=NULL)                  //p左孩子为空结点,且不是根结点
		{  
            q=p;
			p=p->rchild;
            delete  q;
			
			f->rchild =p;
			return true;
		}

		if(!p->lchild&&f==NULL)                  //p左孩子为空结点,且p是根结点
		{  
            q=p;
			p=p->rchild;
			bst=p;
            delete  q;
			return true;
			
		}
         
		if(!p->rchild&&f!=NULL)                 //p右孩子为空结点,且不是根结点
		{ 
			q=p;
			p=p->lchild ;
			delete q;
			
			f->lchild =p;
			return true;
		}

        if(!p->rchild&&f==NULL)                 //p右孩子为空结点,且是根结点
		{ 
			q=p;
			p=p->lchild ;
			bst=p;
  			delete q;
			return true;
			
		}

		else if(p->lchild &&p->rchild )    //p的两个子树都不空
		{
			q=p;
            s=p->lchild ;
			while(s->rchild){q=s;s=s->rchild ;}
			p->key =s->key ;
			if(q!=p)
				q->rchild =s->lchild ;
			else
				q->lchild =s->lchild ;
			delete s;
			
		}
		
	}
    return true;
}

//中序遍历并输出所有结点
void PrintBST(BSTree bst)
{
  if(!bst)
	  cout<<"n\t";
  else 
  {
     PrintBST(bst->lchild);
	 cout<<bst->key<<"\t";
	 PrintBST(bst->rchild); 
  }
}



int main()
{
	BSTree bst=new BSTNode;       //查了半天错误,原来是没有为其分配内存,导致读取内存错误
	bst->key=0;
	bst->lchild=bst->rchild =NULL; 
	 
	cout<<"input the element of the bst, -1 finish : "<<endl;
 	CreateBST(bst);
	PrintBST(bst); cout<<endl;

    DeleteBST(bst,6);
    PrintBST(bst); cout<<endl;
	//BSTree f=GetFather(bst,bst->rchild ->rchild );
	//cout<<f->key<<" "<<endl;

	system("pause");
	return 0;
	
}

测试用例:1  2 3 4 5 6 7 -1

                    5  3  2  4  6  7 -1

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/stevenzhang1986/article/details/6598647
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞