二叉搜索树
当它不为空时,满足如下性质:
当它的左子树不为空时,左子树所有节点都小于根结点的值
当它的右子树不为空时,右子树所有节点都大于根结点的值
它的左右子树分别为二叉搜索树
搜索节点
- 如果根结点不为空
- 如果key和节点的值相等,返回
- 如果key小于节点的值,去左子树查找
- 如果key大于节点的值,去右子树查找
插入节点
- 如果根结点为空
- 直接插入
- 搜索要插入的位置:
- 当前节点不为空时
- 待插入key小于节点值,向左子树走
- 待插入key大于节点值,向右子树走
- 如果相等,直接返回
- 当前节点不为空时
- 插入节点:
- 如果key小于当前节点父节点的值
- 插入到左子树
- 如果key大于当前节点父节点的值
- 插入到右子树
- 如果key小于当前节点父节点的值
删除节点
代码:
#include<iostream>
using namespace std;
template<typename T>
struct BinarySearchNode
{
BinarySearchNode* _pLeft;
BinarySearchNode* _pRight;
T _data;
BinarySearchNode(const T& data=T())
:_pLeft(NULL)
, _pRight(NULL)
, _data(data)
{}
};
template<typename T>
class BinarySerachTree
{
typedef BinarySearchNode<T> Node;
typedef Node* pNode;
public:
BinarySerachTree()
:_pRoot(NULL)
{}
bool Insert(const T& data)
{
if (NULL == _pRoot)
{
_pRoot = new Node(data);
return true;
}
pNode pCur = _pRoot;
pNode pParent = pCur;
while (pCur)
{
if (pCur->_data > data)
{
pParent = pCur;
pCur = pCur->_pLeft;
}
else if (pCur->_data < data)
{
pParent = pCur;
pCur = pCur->_pRight;
}
else
return false;
}
if (pParent->_data < data)
pParent->_pRight = new Node(data);
else
pParent->_pLeft = new Node(data);
return true;
}
pNode Find(const T& data)
{
if (NULL == _pRoot)
return NULL;
pNode pCur = _pRoot;
while (pCur)
{
if (data == pCur->_data)
return pCur;
else if (pCur->_data < data)
pCur = pCur->_pRight;
else
pCUr = pCur->_pLeft;
}
return pCur;
}
bool Delete(const T& data)
{
if (NULL == _pRoot)
return false;
if (NULL == _pRoot->_pLeft && NULL == _pRoot->_pRight)//只有一个节点的情况
{
if (data == _pRoot->_data)
{
delete _pRoot;
_pRoot = NULL;
return true;
}
else
return false;
}
pNode pCur = _pRoot;
pNode pDel = NULL;
pNode pParent = pCur;
while (pCur)
{
if (data == pCur->_data)
{
break;
}
else if (pCur->_data < data)
{
pParent = pCur;
pCur = pCur->_pRight;
}
else
{
pParent = pCur;
pCur = pCur->_pLeft;
}
}
if (NULL == pCur)
return false;
if (NULL == pCur->_pLeft)//要删除节点左边为空或者左右子树都为空
{
if (pCur != _pRoot)
{
if (pParent->_pLeft == pCur)//要删除节点位于上一节点的左边
{
pParent->_pLeft = pCur->_pRight;
}
else if (pParent->_pRight == pCur)
{
pParent->_pRight = pCur->_pRight;
}
}
else
_pRoot = pCur->_pRight;
}
else if (NULL == pCur->_pRight)//待删节点的右边为空
{
if (pCur != _pRoot)
{
if (pParent->_pLeft == pCur)
{
pParent->_pLeft = pCur->_pLeft;
}
else if (pParent->_pRight == pCur)
{
pParent->_pRight = pCur->_pLeft;
}
}
else
_pRoot = pCur->_pLeft;
}
else
//待删节点的左右子树都不为空,
//找到左子树的最右边节点替换待删节点,或者找到右子树的最左边替换待删节点
//然后删除找到的节点
{
pNode pDel = pCur->_pRight;//右子树的根结点
pParent = pCur;
while (pDel->_pLeft)
{
pParent = pDel;
pDel = pDel->_pLeft;
}
pCur->_data = pDel->_data;
pCur = pDel;
if (pDel == pParent->_pLeft)
pParent->_pLeft = pDel->_pRight;
else if (pDel == pParent->_pRight)
pParent->_pRight = pDel->_pRight;
}
delete pCur;
pCur = NULL;
return true;
}
void InOder()
{
if (_pRoot == NULL)
return;
cout << "中序遍历:";
_InOder(_pRoot);
cout << endl;
}
private:
void _InOder(pNode pRoot)
{
if (pRoot == NULL)
return;
_InOder(pRoot->_pLeft);
cout << pRoot->_data << " ";
_InOder(pRoot->_pRight);
}
private:
pNode _pRoot;
};
void BinarySearchTreeTest()
{
BinarySerachTree<int> bs;
int arr[] = {5,7,8,9,6,3,4,1,0,2};
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
{
bs.Insert(arr[i]);
}
bs.InOder();
//bs.Delete(5);
bs.Delete(7);
bs.InOder();
}
递归实现代码:
#pragma once
#include<iostream>
using namespace std;
template<typename T>
struct BinSearchNode
{
BinSearchNode<T>* _pLeft;
BinSearchNode<T>* _pRight;
T _data;
BinSearchNode(const T& data = T())
:_pLeft(NULL)
, _pRight(NULL)
, _data(data)
{}
};
template<typename T>
class BinSearchTree
{
typedef BinSearchNode<T> Node;
typedef Node* pNode;
public:
BinSearchTree()
:_pRoot(NULL)
{}
bool Insert(const T& data)
{
return _Insert(_pRoot, data);
}
pNode Find(const T& data)
{
return _Find(_pRoot, data);
}
bool Delete(const T& data)
{
return _Delete(_pRoot, data);
}
void Inder()
{
if (NULL == _pRoot)
return;
cout << "中序遍历:";
_Inder(_pRoot);
cout << endl;
}
private:
void _Inder(pNode pRoot)
{
if (NULL == pRoot)
return;
_Inder(pRoot->_pLeft);
cout << pRoot->_data << " ";
_Inder(pRoot->_pRight);
}
bool _Delete(pNode& pRoot, const T& data)
{
if (NULL == pRoot)
return false;
if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight)//只有一个节点
{
if (data == pRoot->_data)
{
delete pRoot;
pRoot = NULL;
return true;
}
else
return false;
}
if (data < pRoot->_data)
return _Delete(pRoot->_pLeft, data);
else if (data > pRoot->_data)
return _Delete(pRoot->_pRight,data);
else
{
pNode pDel = pRoot;
if (NULL == pRoot->_pLeft)//当前子树的左子树为空,让根结点指向根结点的左子树
{
pRoot = pRoot->_pRight;
delete pDel;
pDel = NULL;
return true;
}
else if (NULL == pRoot->_pRight)
{
pRoot = pRoot->_pLeft;
delete pDel;
pDel = NULL;
return true;
}
else//左右子树都不为空
{
//找到左右子树的最左边节点-背锅侠,替换根结点
pNode pDel = pRoot;
pDel = pRoot->_pRight;
while (pDel->_pLeft)
pDel = pDel->_pLeft;
pRoot->_data = pDel->_data;
//删除背锅侠
return _Delete(pRoot->_pRight,pDel->_data);
}
}
}
pNode _Find(pNode pRoot, const T& data)
{
if (NULL == pRoot)
return NULL;
if (data == pRoot->_data)
return pRoot;
else if (data < pRoot->_data)
return _Find(pRoot->_pLeft, data);
else
return _Find(pRoot->_pRight,data);
}
bool _Insert(pNode& pRoot, const T& data)
{
if (NULL == pRoot)
{
pRoot = new Node(data);
return true;
}
if (data == pRoot->_data)
return false;
else if (data < pRoot->_data)
return _Insert(pRoot->_pLeft, data);
else
return _Insert(pRoot->_pRight,data);
}
private:
pNode _pRoot;
};
void BinarySearchTreeTest()
{
BinSearchTree<int> bs;
//int arr[] = { 5, 7, 8, 9, 6, 3, 4, 1, 0, 2 };
int arr[] = {5,7,6,9};
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
{
bs.Insert(arr[i]);
}
bs.Inder();
//bs.Delete(5);
bs.Delete(9);
bs.Inder();
}