二叉搜索树(二叉排序数)的基本操作实现

本文实现了二叉搜索树的插入、查找、删除、求最大节点、最小节点以及直接前驱、直接后继节点的基本操作。

先定义一个结构体:

struct Node
{
	int key;
	Node *left;
	Node *right;
	Node *parent;
};

全局变量的定义:
Node* root=NULL;

1、二叉搜索树的插入:

void Insert(int x)
{
	Node *p=root,*q=NULL;

	while(p)//查找带插入位置的双亲节点 q
	{
		q=p;
		if(x<p->key)
			p=p->left;
		else if(x>p->key)
			p=p->right;
	}
	p=new Node;//生成新节点
	p->key=x;
	p->left=p->right=p->parent=NULL;

	if(!root) //插入新节点
		root=p;
	else 
	{
		if(x<q->key)
		{
			p->parent=q;
			q->left=p;
		}
		else 
		{  
			p->parent=q;
			q->right=p;
		}
	}
}
2、二叉搜索树的查找

Node* Search(Node *currentNode,int x)
{
     if(currentNode==NULL)
        return NULL;

     if(x<currentNode->key)
          return Search(currentNode->left,x);
    else if(x>currentNode->key)
           return Search(currentNode->right,x);
         else
         return currentNode; 


}
3、查找最小关键字

Node* SearchMin(Node *node)//一直向下查找左子树
{
	if(node==NULL)
		return NULL;
	if(node->left==NULL)
		return node;
	else
	    return	SearchMin(node->left);
}

4、查找最大关键字

Node* SearchMax(Node *node)//一直向下查找右子树
{
	if(node==NULL)
		return NULL;
	if(node->right==NULL)
		return node;
	else
		return SearchMax(node->right);
}
5、查找节点的直接前驱节点

Node *SearchPredecessor(Node *p)
{
	if(p==NULL)
		return NULL;
	if(p->left)//如有左子树 左子树最大的关键字
		return SearchMax(p->left);
	else
	{
		if(p->parent==NULL)
			return NULL;
		while(p)//向上查找
		{
			if(p->parent->right= =p)
				break;
			p=p->parent;
		}
		return p->parent;
	}
}

6、查找节点的直接后继节点

Node *SearchSuccessor(Node *p)
{
	if(p==NULL)
		return NULL;
	if(p->right)
		return SearchMin(p->right);
	else
	{
		if(p->parent==NULL)
			return NULL;
		while(p)
		{
			if(p->parent->left==p)
				break;
			p=p->parent;
		}
		return p->parent;
	}
}
7、删除

删除分为一下几种情况:

  • 被删除的节点为叶子节点
  • 被删除的节点只有左子树
  • 被删除的节点只有右子树
  • 被删除的节点既有左子树又有右子树

void DeleteNode(int x)
{
	Node* p=Search(root,x);//查找待删除节点
	
	if(p==NULL)
		return;

	if(p->left==NULL&&p->right==NULL)//被删除的节点为叶子节点
	{
		if(p->parent==NULL)
		{
			root=NULL;
		}
		else
		{
			if(p->parent->left==p)
				p->parent->left=NULL;
			else
				p->parent->right=NULL;
		}
	}

	if((p->left!=NULL)&&(p->right==NULL))//被删除的节点只有左子树
	{
		p->left->parent=p->parent;
		if(p->parent==NULL)
		{
			root=p->left;
		}
		else
		{
			if(p->parent->left==p)
				p->parent->left=p->left;
			else
				p->parent->right=p->left;
		}
	}

	if((p->left==NULL)&&(p->right!=NULL))//被删除的节点只有右子树
	{
		p->right->parent=p->parent;
		if(p->parent==NULL)
		{
			root=p->right;
		}
		else
		{
			if(p->parent->left==p)
				p->parent->left=p->right;
			else
				p->parent->right=p->right;
		}
	}

	if(p->left&&p->right)//既有左子树又有右子树
	{
		Node *q;
		q=SearchSuccessor(p);//查找直接后继节点

		int temp=q->key;
		DeleteNode(temp);//删除转换成以上几种情况
		p->key=temp;
	}
    delete p;
}

主函数:

int main()
{
	int keyvalue[12]={15,6,18,3,7,17,20,2,4,13,9,21};
	int length=12;

	for(int i=0;i<length;i++)
	{
		Insert(keyvalue[i]);
	}

	PrintTree(root);
	cout<<endl;

	Node* result=Search(root,13);
	if(result!=NULL)
		cout<<"Found!"<<endl;
	else
		cout<<"None!"<<endl;

	Node* minNode=SearchMin(root);
	cout<<"minNode is :"<<minNode->key<<endl;

	Node* maxNode=SearchMax(root);
	cout<<"maxNode is :"<<maxNode->key<<endl;

    Node* predecessorNode=SearchPredecessor(result);
	cout<<"result's predecessorNode is :"<<predecessorNode->key<<endl;


	DeleteNode(4);  //删除叶子节点   
	PrintTree(root);
	cout<<endl;


	return 0;
}

参考博文:

http://blog.csdn.net/touch_2011/article/details/6831924#t3

http://blog.csdn.net/puqutogether/article/details/40344459#t2


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值