二叉搜索树:又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树
1.若它的左子树不为空,则左子树所有结点的值都小于根节点的值。
2.若它的右子树不为空,则右子树所有结点的值都大于根节点的值。
3.它的左右子树也分别为二叉搜索树。
下面是关于二叉搜索树的实现,其中比较难以操作的就是删除操作。我们来分析一下删除操作都有哪几种情况:
首先查找元素是否在二叉搜索树中,若不存在,则返回;否则要删除的可能分一下四种情况:
1.要删除的结点无孩子结点,那么可直接进行删除。
2.要删除的结点只有左孩子结点,则删除该结点,让被删除结点的双亲结点指向被删除结点的左孩子。
3.要删除的结点只有右孩子结点,则删除该结点,让被删除结点的双亲结点指向被删除结点的有孩子。
4.要删除的结点有左右孩子结点,则在该结点的右子树中寻找关键码最小的结点,或在该结点的左子树中寻找关键码最大的结点,然后两值进行交换,然后删除该删除的结点。
如图:
代码如下:
#pragma once
#include<iostream>
using namespace std;
template<class K,class V>
struct BSTreeNode
{
BSTreeNode<K,V>* _pleft;
BSTreeNode<K, V>* _pright;
K _key;
V _value;
BSTreeNode(const K& key, const V& value)
:_key(key)
, _value(value)
, _pleft(NULL)
, _pright(NULL)
{}
};
template<class K,class V>
class BSTree
{
typedef BSTreeNode<K,V> Node;
public:
BSTree()
: _pRoot(NULL)
{}
~BSTree()
{}
BSTree(const BSTree& bst)
{
_pRoot = _Copy(bst);
}
BSTree<K, V>& operator=(const BSTree<K, V>& bst)
{
if (this != bst)
{
Node* tmp = _Copy(bst._pRoot);
_pRoot = _Destroy(bst._pRoot);
_pRoot = tmp;
}
return *this;
}
Node* Find(const K& key)
{
return _Find(key);
}
bool Insert(const K& key, const V& value)
{
return _Insert(key, value);
}
bool Remove(const K& key)
{
//return _Remove(key);
return _Remove_R(_pRoot, key);
}
void InOrder()
{
cout << "InOrder: ";
_InOrder(_pRoot);
cout << endl;
}
const K& GetMaxKey()const
{
while(_pRoot)
{
_pRoot = _pRoot->_pleft;
}
return _pRoot->_key;
}
const K& GetMinKey()const
{
while (_pRoot)
{
_pRoot = _pRoot->_pright;
}
return _pRoot->_key;
}
protected:
bool _Insert(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)
{
pParent = pCur;
pCur = pCur->_pleft;
}
else if (key>pCur->_key)
{
pParent = pCur;
pCur = pCur->_pright;
}
else
return false;
}
pCur = new Node(key, value);
if (key < pParent->_key)
pParent->_pleft = pCur;
else
pParent->_pright = pCur;
return true;
}
//_Insert递归
bool _Insert_R(Node* pRoot, const K& key, const V& value)
{
if (pRoot == NULL)
{
pRoot = new Node(key, value);
return true;
}
if (pRoot)
{
if (pRoot->_key > key)
return _Insert_R(pRoot->_pleft, key, value);
if (pRoot->_key < key)
return _Insert_R(pRoot->_pright, key, value);
else
return false;
}
}
Node* _Copy(const BSTree& bst)
{
Node* newNode = NULL;
if (_pRoot != NULL)
{
Node newNode = new Node(bst._pRoot->_key, bst._pRoot->_value);
newNode->_pleft = _Copy(bst._pRoot->_pleft);
newNode->_prigth = _Copy(bst._pRoot->_pright);
}
return newNode;
}
Node* _Find(const K& key)
{
Node* pCur = _pRoot;
while (pCur)
{
if (pCur->_key > key)
pCur = pCur->_pleft;
else if (pCur->_key < key)
pCur = pCur->_pright;
else
return pCur;
}
return NULL;
}
//_Find递归
Node* _Find_R(Node* pRoot,const K& key)
{
if (pRoot)
{
if (pRoot->_key > key)
{
return _Find_R(pRoot->_pleft, key);
}
if (pRoot->_key < key)
{
return _Find_R(pRoot->_pright, key);
}
else
return pRoot;
}
return NULL;
}
void _InOrder(Node* pRoot)
{
if (pRoot)
{
_InOrder(pRoot->_pleft);
cout << pRoot->_key << " ";
_InOrder(pRoot->_pright);
}
}
bool _Remove(const K&key)
{
if (_pRoot == NULL)
{
return false;
}
Node* del = _pRoot;
Node* pParent = NULL;
while (del)
{
//找到待删除节点
if (del->_key > key)
{
pParent = del;
del = del->_pleft;
}
else if (del->_key < key)
{
pParent = del;
del = del->_pright;
}
else
{
break;
}
}
if (del)
{
if (NULL == del->_pleft)
{
if (del != _pRoot)
{
if (pParent->_pright == del)
{
pParent->_pright = del->_pright;
}
else
{
pParent->_pleft = del->_pright;
}
}
else
{
_pRoot = del->_pright;
}
}
else if (NULL == del->_pright)
{
if (del != _pRoot)
{
if (pParent->_pright == del)
{
pParent->_pright = del->_pleft;
}
else
{
pParent->_pleft = del->_pleft;
}
}
else
{
_pRoot = del->_pleft;
}
}
else
{
//查找右子树中中序遍历的第一个节点,进行替换,然后删除
Node* firstInOrder = del->_pright;
Node* pParent = del;
while (firstInOrder->_pleft)
{
pParent = firstInOrder;
firstInOrder=firstInOrder->_pleft;
}
std::swap(del->_key, firstInOrder->_key);
std::swap(del->_value, firstInOrder->_value);
if (pParent->_pleft ==firstInOrder )
{
pParent->_pleft = firstInOrder->_pright;
}
else
{
pParent->_pright = firstInOrder->_pright;
}
del=firstInOrder;
}
delete del;
}
else
{
return false;
}
return true;
}
//_Remove_R递归
bool _Remove_R(Node* pRoot, const K& key)
{
if (pRoot)
{
if (pRoot->_key > key)
return _Remove_R(pRoot->_pleft, key);
if (pRoot->_key < key)
return _Remove_R(pRoot->_pright, key);
else
{
if (pRoot->_pleft == NULL)
{
Node* del = pRoot;
pRoot = pRoot->_pright;
delete del;
}
else if (pRoot->_pright == NULL)
{
Node* del = pRoot;
pRoot = pRoot->_pleft;
delete del;
}
else
{
Node* right = pRoot->_pright;
while (right->_pleft)
{
right = right->_pleft;
}
swap(pRoot->_key, right->_key);
swap(pRoot->_value, right->_value);
_Remove_R(pRoot->_pright, right->_key);
}
return true;
}
}
return false;
}
private:
Node* _pRoot;
};
下面是加入了迭代器的优化版本:
#pragma once
#include <iostream>
using namespace std;
#include <assert.h>
template<class K,class V>
struct Node
{
Node()
{}
Node(const K& key,const V& value)
:_key(key)
,_value(value)
,_parent(NULL)
,_pLeft(NULL)
,_pRight(NULL)
{}
K _key;
V _value;
Node<K,V>* _parent;
Node<K,V>* _pLeft;
Node<K,V>* _pRight;
};
//迭代器
template<class K,class V,class Ref,class Ptr>
class BstIterator
{
typedef Node<K,V> Node;
typedef BstIterator<K,V,Ref,Ptr> Self;
public:
BstIterator()
:_pNode(NULL)
{}
BstIterator(Node* pNode)
:_pNode(pNode)
{}
BstIterator(const Self& s)
{
_pNode=s._pNode;
}
Self& operator++()
{
Increase(_pNode);
return *this;
}
Self operator++(int)
{
Self tmp(*this);
Increase(_pNode);
return tmp;
}
Self& operator--()
{
Decrease(_pNode);
return *this;
}
Self operator--(int)
{
Self tmp(*this);
Decrease(_pNode);
return tmp;
}
Ref operator*()
{
return _pNode->_key;
}
Ptr operator->()
{
return _pNode;
}
bool operator!=(const Self& s)
{
return (_pNode!=s._pNode);
}
bool operator==(const Self& s)
{
return !(*this!=s);
}
private:
void Increase(Node*& pNode)
{
assert(pNode);
if(pNode->_pRight)
{
pNode=pNode->_pRight;
while(pNode->_pLeft)
{
pNode=pNode->_pLeft;
}
}
else
{
Node* parent=pNode->_parent;
while(pNode==parent->_pRight)
{
pNode=parent;
parent=pNode->_parent;
}
if(pNode->_pRight!=parent)
{
pNode=parent;
}
}
}
void Decrease(Node*& pNode)
{
assert(pNode);
if(pNode->_pLeft)
{
pNode=pNode->_pLeft;
while(pNode->_pRight)
{
pNode=pNode->_pRight;
}
}
else
{
Node* parent=pNode->_parent;
while(pNode==parent->_pLeft)
{
pNode=parent;
parent=pNode->_parent;
}
pNode=parent;
}
}
private:
Node* _pNode;
};
template<class K,class V>
class BinarySearchTree
{
typedef Node<K,V> Node;
typedef BstIterator<K,V,K,Node*> BstIterator;
public:
BinarySearchTree()
{
_pHead=new Node;
_pHead->_pLeft=_pHead;
_pHead->_pRight=_pHead;
_pHead->_parent=NULL;
}
BinarySearchTree(const BinarySearchTree<K,V>& bst)
{
Node* pRoot=GetRoot();
pRoot=_CopyTree(bst._pHead);
}
BinarySearchTree<K, V>& operator=(const BinarySearchTree<K, V>& bst)
{
if(this!=&bst)
{
Node* pRoot=GetRoot();
Destory(pRoot);
pRoot=_CopyTree(bst._pHead);
}
return *this;
}
BstIterator Begin()
{
BstIterator it(MostLeft());
return it;
}
BstIterator End()
{
BstIterator it(_pHead);
return it;
}
~BinarySearchTree()
{
Node* pRoot=GetRoot();
Destory(pRoot);
delete _pHead;
}
Node* Find(const K& key)
{
Node* pRoot=GetRoot();
return _Find(pRoot,key);
}
bool Insert(const K& key, const V& value)
{
return _Insert(_pHead,key,value);
}
bool Remove(const K& key)
{
return _Remove(_pHead,key);
}
void InOrder()
{
Node* pRoot=GetRoot();
cout<<"InOrder: ";
_InOrder(pRoot);
cout<<endl;
}
const K& GetMaxKey()const
{
Node* pcur=GetRoot();
while(pcur->_pRight)
pcur=pcur->_pRight;
return pcur->_key;
}
const K& GetMinKey()const
{
Node* pcur=GetRoot();
while(pcur->_pLeft)
pcur=pcur->_pLeft;
return pcur->_key;
}
//转换成有序双向链表
Node* ToList()
{
Node* pRoot=GetRoot();
Node* pre=NULL;
_ToList(pRoot,pre);
return MostLeft();
}
protected:
void _ToList(Node* pRoot,Node*& pre)
{
if(pRoot==NULL)
return ;
_ToList(pRoot->_pLeft,pre);
pRoot->_pLeft=pre;
if(pre)
pre->_pRight=pRoot;
pre=pRoot;
_ToList(pRoot->_pRight,pre);
}
Node* GetRoot()
{
return _pHead->_parent;
}
Node* MostLeft()
{
Node* pRoot=GetRoot();
if(pRoot==NULL)
return NULL;
while(pRoot->_pLeft)
{
pRoot=pRoot->_pLeft;
}
return pRoot;
}
Node* MostRight()
{
Node* pRoot=GetRoot();
if(pRoot==NULL)
return NULL;
while(pRoot->_pRight)
{
pRoot=pRoot->_pRight;
}
return pRoot;
}
Node* _CopyTree(Node* pHead)
{
Node* pRoot=GetRoot();
if(pRoot==NULL)
return NULL;
Node* ptmp=new Node(pRoot->_key,pRoot->_value);
ptmp->_pLeft=_CopyTree(pRoot->_pLeft);
ptmp->_pRight=_CopyTree(pRoot->_pRight);
return ptmp;
}
void Destory(Node*& pRoot)
{
if(pRoot)
{
Destory(pRoot->_pLeft);
Destory(pRoot->_pRight);
delete pRoot;
}
}
Node* _Find(Node* pRoot,const K& key)
{
if(pRoot==NULL)
return NULL;
while(pRoot)
{
if(key<pRoot->_key)
{
pRoot=pRoot->_pLeft;
}
else if(key>pRoot->_key)
{
pRoot=pRoot->_pRight;
}
else
return pRoot;
}
return NULL;
}
bool _Insert(Node*& pHead,const K& key,const V& value)
{
Node* pRoot=GetRoot();
if(pRoot==NULL)
{
pRoot=new Node(key,value);
pRoot->_parent=pHead;
pHead->_parent=pRoot;
}
else
{
Node* pcur=pRoot;
Node* parent=NULL;
while(pcur)
{
if(pcur->_key==key)
return false;
else if(key<pcur->_key)
{
parent=pcur;
pcur=pcur->_pLeft;
}
else
{
parent=pcur;
pcur=pcur->_pRight;
}
}
pcur=new Node(key,value);
pcur->_parent=parent;
if(key<parent->_key)
parent->_pLeft=pcur;
else
parent->_pRight=pcur;
}
pHead->_pLeft=MostLeft();
pHead->_pRight=MostRight();
return true;
}
bool _Remove(Node*& pHead,const K& key)
{
Node* pRoot=GetRoot();
if(pRoot==NULL)
return false;
Node* pcur=pRoot;
Node* parent=NULL;
while(pcur)
{
if(key<pcur->_key)
{
parent=pcur;
pcur=pcur->_pLeft;
}
else if(key>pcur->_key)
{
parent=pcur;
pcur=pcur->_pRight;
}
else
{
if(pcur->_pLeft==NULL)
{
if(pcur==pRoot)
{
pRoot=pcur->_pRight;
pHead->_parent=pRoot;
pRoot->_parent=pHead;
}
else if(pcur==parent->_pLeft)
{
parent->_pLeft=pcur->_pRight;
if(pcur->_pRight)
pcur->_pRight->_parent=parent;
}
else
{
parent->_pRight=pcur->_pRight;
if(pcur->_pRight)
pcur->_pRight->_parent=parent;
}
}
else if(pcur->_pRight==NULL)
{
if(pcur==pRoot)
{
pRoot=pcur->_pLeft;
pHead->_parent=pRoot;
pRoot->_parent=pHead;
}
else if(pcur==parent->_pLeft)
{
parent->_pLeft=pcur->_pLeft;
if(pcur->_pLeft)
pcur->_pLeft->_parent=parent;
}
else
{
parent->_pRight=pcur->_pLeft;
if(pcur->_pLeft)
pcur->_pLeft->_parent=parent;
}
}
else
{
Node* pDel=pcur;
parent=pcur;
pDel=pDel->_pRight;
while(pDel->_pLeft)
{
parent=pDel;
pDel=pDel->_pLeft;
}
pcur->_key=pDel->_key;
pcur->_value=pDel->_value;
if(pDel==parent->_pLeft)
{
parent->_pLeft=pDel->_pRight;
}
else
{
parent->_pLeft=pDel->_pRight;
}
if(pDel->_pRight)
pDel->_pRight->_parent=parent;
pcur=pDel;
}
delete pcur;
pHead->_pLeft=MostLeft();
pHead->_pRight=MostRight();
return true;
}
}
return false;
}
void _InOrder(Node* pRoot)
{
if(pRoot)
{
_InOrder(pRoot->_pLeft);
cout<<pRoot->_key<<" ";
_InOrder(pRoot->_pRight);
}
}
private:
Node* _pHead;
};