二叉搜索树又称二叉排序树他是一颗空树或者具有一下性质的树
若他的左子树不为空那么它的左子树的所有节点的键值都小于根节点的键值
若他的右子树不为空那么它的右子树的所有节点的键值都大于根节点的键值
它的左右字数也是二叉搜索树
对于二叉搜索树查找一个节点在一般情况下具有O(log2(n))的时间复杂度对于单支的情况下退化为O(n)
本文采用键值对的方式实现二叉搜索树,建立二叉搜索树是通过插入一个个的节点来实现
#pragma once
#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
{
typedef BSTNode<K, V> Node;
typedef BinarySearchTree<K, V> Self;
public:
BinarySearchTree()
: _pRoot(NULL)
{}
BinarySearchTree(const Self& bst)
{
if (bst._pRoot == NULL)
{
_pRoot = NULL;
return;
}
_Copy(_pRoot, bst._pRoot);
}
Self& operator=(const Self& bst)
{
if (this == &bst)
{
return *this;
}
if (bst._pRoot == NULL)
{
_pRoot = NULL;
return *this;
}
Node* Root = NULL;
_Copy(Root, bst._pRoot);
if (Root)
{
Destroy(_pRoot);
_pRoot = Root;
}
return *this;
}
~BinarySearchTree()
{
Destroy(_pRoot);
}
// 查找递归和非递归
bool Find_Nor(const K& key)
{
if (NULL == _pRoot)
return false;
Node* pCur = _pRoot;
while (pCur)
{
if (key == pCur->_key)
return true;
else if (key > pCur->_key)
pCur = pCur->_pRight;
else
pCur = pCur->_pLeft;
}
return false;
}
bool Find(const K& key)
{
return _Find(_pRoot, key);
}
// 插入递归和非递归
bool Insert_Nor(const K& key, const V& value)
{
if (NULL == _pRoot)
{
_pRoot = new Node(key, value);
return true;
}
Node* pCur = _pRoot;
Node* pParent = NULL;
while (pCur)
{
if (key == pCur->_key)
return false;
else if (key > pCur->_key)
{
pParent = pCur;
pCur = pCur->_pRight;
}
else
{
pParent = pCur;
pCur = pCur->_pLeft;
}
}
if (pParent->_key > key)
{
pParent->_pLeft = new Node(key, value);
return true;
}
else
{
pParent->_pRight = new Node(key, value);
return true;
}
return false;
}
bool Insert(const K& key, const V& value)
{
return _Insert(_pRoot, key, value);
}
// 删除递归和非递归
bool Remove_Nor(const K& key)
{
if (_pRoot == NULL)
{
return false;
}
if (_pRoot->_pLeft == NULL && _pRoot->_pRight == NULL && _pRoot->_key == key)
{
delete _pRoot;
_pRoot = NULL;
return true;
}
Node* pCur = _pRoot;
Node* pParent = NULL;
while (pCur)
{
if (key > pCur->_key)
{
pParent = pCur;
pCur = pCur->_pRight;
}
else if (key < pCur->_key)
{
pParent = pCur;
pCur = pCur->_pLeft;
}
else
break;
}
if (pCur)
{
if (pCur->_pLeft == NULL)
{
if (_pRoot == pCur)
{
_pRoot = pCur->_pRight;
delete pCur;
pCur = NULL;
return true;
}
else
{
if (pCur == pParent->_pLeft)
{
pParent->_pLeft = pCur->_pRight;
delete pCur;
pCur = NULL;
return true;
}
else
{
pParent->_pRight = pCur->_pRight;
delete pCur;
pCur = NULL;
return true;
}
}
}
else if (pCur->_pRight == NULL)
{
if (_pRoot == pCur)
{
_pRoot = pCur->_pLeft;
delete pCur;
pCur = NULL;
return true;
}
else if (pParent->_pLeft == pCur)
{
pParent->_pLeft = pCur->_pLeft;
delete pCur;
pCur = NULL;
return true;
}
else
{
pParent->_pRight = pCur->_pLeft;
delete pCur;
pCur = NULL;
return true;
}
}
else
{
Node* firstInOrder = pCur->_pRight;
pParent = pCur;
while (firstInOrder->_pLeft)
{
pParent = firstInOrder;
firstInOrder = firstInOrder->_pLeft;
}
pCur->_key = firstInOrder->_key;
pCur->_value = firstInOrder->_value;
if (pParent == pCur)
{
pCur->_pRight = firstInOrder->_pRight;
delete firstInOrder;
return true;
}
else
{
pParent->_pLeft = firstInOrder->_pRight;
delete firstInOrder;
return true;
}
}
}
return false;
}
bool Remove(const K& key)
{
return _Remove(_pRoot, key);
}
void InOrder()
{
cout << "InOrder:";
_InOrder(_pRoot);
cout << endl;
}
private:
bool _Find(Node* pRoot, const K& key)
{
if (NULL == pRoot)
return false;
if (key == pRoot->_key)
return true;
if (pRoot->_key < key)
return _Find(pRoot->_pRight, key);
else
return _Find(pRoot->_pLeft, key);
}
bool _Insert(Node* &pRoot, const K& key, const V& value)
{
if (NULL == pRoot)
{
pRoot = new Node(key, value);
return true;
}
if (key == pRoot->_key)
{
return false;
}
if (pRoot->_key < key)
return _Insert(pRoot->_pRight, key, value);
else
return _Insert(pRoot->_pLeft, key, value);
}
bool _Remove(Node*& pRoot, const K& key)
{
if (pRoot == NULL)
{
return false;
}
if (pRoot->_key == key)
{
if (pRoot->_pLeft == NULL)
{
Node* pCur = pRoot;
pRoot = pRoot->_pRight;
delete pCur;
return true;
}
else if (pRoot->_pRight == NULL)
{
Node* pCur = pRoot;
pRoot = pRoot->_pLeft;
delete pCur;
return true;
}
else
{
Node* firstInOrder = pRoot->_pRight;
while (firstInOrder->_pLeft)
firstInOrder = firstInOrder->_pLeft;
pRoot->_key = firstInOrder->_key;
pRoot->_value = firstInOrder->_value;
return _Remove(pRoot->_pRight, firstInOrder->_key);
}
}
if (key > pRoot->_key)
return _Remove(pRoot->_pRight, key);
else
return _Remove(pRoot->_pLeft, key);
}
void _InOrder(Node* pRoot)
{
if (pRoot)
{
_InOrder(pRoot->_pLeft);
cout << pRoot->_key << " ";
_InOrder(pRoot->_pRight);
}
}
void Destroy(Node*& pRoot)
{
if (NULL == pRoot)
{
return;
}
Destroy(pRoot->_pLeft);
Destroy(pRoot->_pRight);
delete pRoot;
pRoot = NULL;
}
void _Copy(Node*& pRoot, const Node* pDes)
{
if (pDes)
{
pRoot = new Node(pDes->_key, pDes->_value);
_Copy(pRoot->_pLeft, pDes->_pLeft);
_Copy(pRoot->_pRight, pDes->_pRight);
}
}
private:
Node* _pRoot;
};