二叉搜索树的插入、查找、删除等操作

二叉搜索树:又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树

1、若它的左子树不为空,则左子树上所有节点的值都小于根节点的值

2、若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

3、它的左右子树也分别为二叉搜索树

查找(key为要查找的值):

if(pRoot==NULL) return false  

else  

若pRoot->key==key, return true  

若pRoot->key>key,在其左子树中查找

若pRoot->key<key,在其右子树中查找  

插入(key为要插入的值): 在向二叉搜索树中插入新元素时,必须先检测这个元素是否在树中已经存在。如果搜索成功,说明该元素已经存在,则不进行插入;否则将新元素加入到搜索停止的地方。

首先查找插入位置,再插入结点(pRoot==NULL,直接插入并返回true)。

删除(key为要删除的值): 首先查找元素是否在二叉搜索树中,如果不存在,则返回;否则分以下四种情况: 1、要删除的结点无孩子结点,则直接删除; 

2、要删除的孩子只有左孩子结点,删除该结点且使被删除结点的双亲结点指向被删除结点的左孩子结点;

3、要删除的孩子只有右孩子结点,删除该结点且使被删除结点的双亲结点指向被删除结点的右孩子结点;  

4、要删除的结点左右孩子都存在,则在它的右子树中找中序遍历的第一个结点(即值最小的结点),用它的值填补到被删除的结点中,再来处理该结点的删除问题。 

具体代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<iostream>
using namespace std;
template<class K,class V>
struct BSTNode
{
	BSTNode(const K& key, const V& value)
	:_pLeft(NULL)
	,_pRight(NULL)
	,_key(key)
	,_value(value)
	{}
	BSTNode<K, V>* _pLeft;
	BSTNode<K, V>* _pRight;
	K _key;
	V _value;
};
//二叉搜索树:如果有左子树,左子树的值<根的值;如果有右子树,右子树的值>根的值
template<class K,class V>
class BinarySearchTree
{
public:
	BinarySearchTree()
		:pRoot(NULL)
	{}
	bool Insert(const K& key, const V& value)
	{
		if (pRoot == NULL)
			pRoot = new BSTNode<K, V>(key, value);
		//找插入位置
		BSTNode<K, V>* pCur = pRoot;
		BSTNode<K, V>* pParent = NULL;
		while (pCur)
		{
			if (pCur->_key < key)
			{
				pParent = pCur;
				pCur = pCur->_pRight;
			}
			else if (pCur->_key>key)
			{
				pParent = pCur;
				pCur = pCur->_pLeft;
			}
			else
				return false;
		}
		//插入结点	
        BSTNode<K,V>* newNode = new BSTNode<K, V>(key,value);
		if (pParent->_key < key)
			pParent->_pRight = newNode;	
	    else
			pParent->_pLeft = newNode;
		return true;
	}
	bool Find(const K& key)
	{
		BSTNode<K, V>* pCur = pRoot;
		while (pCur)
		{
			if (pCur->_key < key)
			{
				pCur = pCur->_pRight;
			}
			else if (pCur->_key>key)
			{
				pCur = pCur->_pLeft;
			}
			else
			{
				return true;
			}
		}
		return false;
	}
	bool Remove(const K& key)
	{
		//树为空
		if (pRoot == NULL)
			return false;
		//只有根节点
		if (pRoot->_pLeft == NULL && pRoot->_pRight == NULL)
		{
			if (pRoot->_key == key)
			{
				delete pRoot;
				pRoot = NULL;
				return true;
			}
			return false;
		}
		//找删除结点的位置
		BSTNode<K, V>* pCur = pRoot;
		BSTNode<K, V>* pParent = NULL;	
		while (pCur && pCur->_key!=key)
		{
			if (pCur->_key < key)
			{
				pParent = pCur;
				pCur = pCur->_pRight;
			}
			if (pCur->_key > key)
			{
				pParent = pCur;
				pCur = pCur->_pLeft;
			}
		}	
		if (pCur)
		{
			//pCur只有左子树
			if (pCur->_pRight == NULL)
			{
				if (pCur == pRoot)
				{
					pRoot = pCur->_pLeft;
				}
				else if (pParent->_pRight = pCur)
				{
					pParent->_pRight = pCur->_pLeft;
				}
				else
				{
					pParent->_pLeft = pCur->_pLeft;
				}
				delete pCur;
			}
			//pCur只有右子树
			else if (pCur->_pLeft == NULL)
			{
				if (pCur == pRoot)
				{
					pRoot = pCur->_pRight;
				}
				if (pParent->_pLeft = pCur)
				{
					pParent->_pLeft = pCur->_pRight;
				}
				else
				{
					pParent->_pRight = pCur->_pRight;
				}
				delete pCur;
			}
			else
			{
				//pCur左右子树都存在,找pCur右子树中序遍历的第一个节点(即右子树中值最小的结点)
				BSTNode<K, V>* RFirstInorder = pCur->_pRight;
				while (RFirstInorder->_pLeft)
				{
					pParent = RFirstInorder;
					RFirstInorder = RFirstInorder->_pLeft;
				}
				//将pCur的key和value与RFirstInorder的key和value进行交换
				RFirstInorder->_key = pCur->_key;
				RFirstInorder->_value = pCur->_value;
				if (pParent->_pLeft == RFirstInorder)
				{
					pParent->_pLeft = RFirstInorder->_pRight;
				}
				else
				{
					pParent->_pRight = RFirstInorder->_pRight;
				}
				pCur = RFirstInorder;
				delete pCur;
			}
		}
		return true;
}
private:
	BSTNode<K, V>* pRoot;
};
void test()
{
	BinarySearchTree<int, int> bst;
	bst.Insert(5, 5);
	bst.Insert(2, 2);
	bst.Insert(1, 1);
	bst.Insert(3, 3);
	bst.Insert(4, 4);
	bst.Insert(0, 0);
	bst.Insert(7, 7);
	bst.Insert(8, 8);
	bst.Insert(6, 6 );
    cout << bst.Find(3) << endl;
	cout << bst.Find(10) << endl;
	cout << bst.Find(43) << endl;
	cout << bst.Find(6) << endl;
	cout << bst.Remove(4) << endl;
	cout << bst.Remove(7) << endl;

}
int main()
{
	test();
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值