二叉搜索树:又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树
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;
}