二叉搜索树及其基本操作
1.二叉搜索树的概念
二叉搜索树又称为二叉排序树,它或者是一颗空树,或者是具有以下性质的二叉树:
- 若它的左子树不为空,则其左子树上所有节点的值都小于其根结点的值
- 若它的右子树不为空,则其右子树上所有节点的值都大于其根结点的值
- 它的左右子树也都是二叉搜索树
2.二叉搜索树的基本操作
2.1二叉搜索树的查找
原理:
若根结点不为空:
如果根结点key==查找key 返回true
如果根结点key>查找key 在其左子树查找
如果根结点key<查找key 在其右子树查找
代码实现:
Node* Find(const T& data) {
if (_pRoot == nullptr) {
return NULL;
}
Node* pCur = _pRoot;
while (pCur) {
if (data == pCur->_data) {
return pCur;
}
else if (data < pCur->_data) {
pCur = pCur->_pLeft;
}
else {
pCur = pCur->_pRight;
}
}
return nullptr;
}
2.2二叉搜索树的插入
插入过程:
1. 树为空,直接插入
2. 树不空,按二叉搜索树性质找到插入位置,插入结点
代码如下:
bool Insert(const T& data) {
if (_pRoot == nullptr) {
_pRoot = new Node(data);
return true;
}
Node* pCur = _pRoot;
Node* pParent = nullptr;
while (pCur) {
pParent = pCur;
if (data < pCur->_data) {
pCur = pCur->_pLeft;
}
else if (data > pCur->_data) {
pCur = pCur->_pRight;
}
else {
return false;
}
}
pCur = new Node(data);
if (data < pParent->_data) {
pParent->_pLeft = pCur;
}
else {
pParent->_pRight = pCur;
}
return true;
}
2.3 二叉搜索树的删除
首先查找元素是否在二叉搜索树中,如果不存在,则返回
bool Delete(const T& data) {
if (_pRoot == nullptr) {
return false;
}
Node* pCur = _pRoot;
Node* pParent = nullptr;
while (pCur) {
if (pCur->_data == data) {
break;
}
else if (data < pCur->_data) {
pParent = pCur;
pCur = pCur->_pLeft;
}
else {
pParent = pCur;
pCur = pCur->_pRight;
}
}
if (pCur == nullptr) {
return false;
}
否则要删除的结点可能分为下面三种情况
要删除的结点只有左孩子
else if (nullptr == pCur->_pRight) {
if (nullptr==pParent) {
_pRoot = pCur->_pLeft;
}
else {
if (pCur == pParent->_pLeft) {
pParent->_pLeft = pCur->_pLeft;
}
else {
pParent->_pRight = pCur->_pLeft;
}
}
}
要删除的结点只有右孩子
if (nullptr == pCur->_pLeft) {
if (nullptr==pParent) {
_pRoot= pCur->_pRight;
}
else {
if (pCur = pParent->_pLeft) {
pParent->_pLeft = pCur->_pRight;
}
else {
pParent->_pRight = pCur->_pRight;
}
}
}
要删除的孩子左右孩子都有
else {
Node* pDelNode = pCur->_pRight;
pParent = pCur;
while (pDelNode->_pLeft) {
pParent = pDelNode;
pDelNode = pDelNode->_pLeft;
}
pCur->_data = pDelNode->_data;
if (pDelNode == pParent->_pLeft) {
pParent->_pLeft = pDelNode->_pRight;
}
else {
pParent->_pRight = pDelNode->_pRight;
}
pCur = pDelNode;
}
具体删除代码如下:
bool Delete(const T& data) {
if (_pRoot == nullptr) {
return false;
}
Node* pCur = _pRoot;
Node* pParent = nullptr;
while (pCur) {
if (pCur->_data == data) {
break;
}
else if (data < pCur->_data) {
pParent = pCur;
pCur = pCur->_pLeft;
}
else {
pParent = pCur;
pCur = pCur->_pRight;
}
}
if (pCur == nullptr) {
return false;
}
if (nullptr == pCur->_pLeft) {
if (nullptr==pParent) {
_pRoot= pCur->_pRight;
}
else {
if (pCur = pParent->_pLeft) {
pParent->_pLeft = pCur->_pRight;
}
else {
pParent->_pRight = pCur->_pRight;
}
}
}
else if (nullptr == pCur->_pRight) {
if (nullptr==pParent) {
_pRoot = pCur->_pLeft;
}
else {
if (pCur == pParent->_pLeft) {
pParent->_pLeft = pCur->_pLeft;
}
else {
pParent->_pRight = pCur->_pLeft;
}
}
}
else {
Node* pDelNode = pCur->_pRight;
pParent = pCur;
while (pDelNode->_pLeft) {
pParent = pDelNode;
pDelNode = pDelNode->_pLeft;
}
pCur->_data = pDelNode->_data;
if (pDelNode == pParent->_pLeft) {
pParent->_pLeft = pDelNode->_pRight;
}
else {
pParent->_pRight = pDelNode->_pRight;
}
pCur = pDelNode;
}
delete pCur;
return true;
}