二叉搜索树又称二叉排序树,它或者是一颗空树,有以下性质:
int a[ ] = { 5,3,4,1,7,8,2,6,0,9};
1、查找步骤
若根结点不为空:
否则返回false;
2、代码
PNode Find(const T& data) {
PNode pCur = _pRoot;
while (pCur) {
if (pCur->_data == data)
return _pRoot;
else if (pCur->_data < data)
pCur = _pRoot->_pLeft;
else if (pCur->_data > data)
pCur = _pRoot->_pRight;
}
return nullptr;
}
1、插入过程:
2、代码
bool Insert(const T& data) {
//空树
if (_pRoot == nullptr) {
_pRoot = new Node(data);
return true;
}
//树不为空,找到位置
PNode pCur = _pRoot;
PNode pParent = nullptr;
while (pCur) {
pParent = pCur;
if (pCur->_data > data) {
pCur = pCur->_pLeft;
}
else if (pCur->_data < data) {
pCur = pCur->_pRight;
}
else {
return false;
}
}
//插入
pCur = new Node(data);
if (data < pParent->_data) {
pParent->_pLeft = pCur;
}
else {
pParent->_pRight = pCur;
}
return true;
}
1、首先查找元素是否在二叉树中,如果不存在,则返回,否则要删除的结点存在四种情况:
2、实际上只有三种情况待处理(无孩子结点和只有左或只有右孩子的情况可以合并),真正的删除过程如下:
3、代码
bool Erase(const T & data) {
if (_pRoot == nullptr)
return false;
PNode pCur = _pRoot;
PNode pParent = nullptr;
//寻找该结点
while (pCur) {
if (pCur->_data > data) {
pParent = pCur;
pCur = pCur->_pLeft;
}
else if (pCur->_data < data) {
pParent = pCur;
pCur = pCur->_pRight;
}
else
break;
}
if (pCur == nullptr)
return false;
//结点找到后,分情况处理
//1、要删除的结点只有右孩子
//2、要删除的结点只有左孩子
//3、要删除的结点左右孩子都有
Node* pDelNode = pCur;
if (pCur->_pLeft == nullptr) {
if (pCur == _pRoot) {
_pRoot = pCur->_pRight;
}
else {
if (pCur == pParent->_pLeft) {
pParent->_pLeft = pCur->_pRight;
}
else {
pParent->_pRight = pCur->_pRight;
}
}
}
else if (pCur->_pRight == nullptr) {
if (pCur == _pRoot) {
_pRoot = pCur->_pLeft;
}
else {
if (pCur == pParent->_pRight) {
pParent->_pLeft = pCur->_pLeft;
}
else {
pParent->_pRight = pCur->_pLeft;
}
}
}
else {
//找到右侧最小的节点来替换,pRet一定没有左孩子!!
Node* pRet = pCur->_pRight;
pParent = pCur;
while (pRet->_pLeft) {
pParent = pRet;
pRet = pRet->_pLeft;
}
pCur->_data = pRet->_data;
//如果 pRet 是根结点直接删除
if (pRet == pParent->_pLeft) {
pParent->_pLeft = pRet->_pRight;
}
else {
pParent->_pRight = pRet->_pRight;
}
pDelNode = pRet;
}
delete pDelNode;
return true;
}
插入 和 删除 操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。
最优情况下:二叉搜索树为完全二叉树,其平均比较次数为:log2N;
最差情况下:二叉搜索树退化为单支树,其平均比较次数为:N / 2;
#pragma once
#include
#include
#include
using namespace std;
template
struct BSTNode {
BSTNode(const T& data = T)
:_pLeft(nullptr)
, _pRight(nullptr)
, _data(data)
{}
BSTNode* _pLeft;
BSTNode* _pRight;
T _data;
};
template
class BSTree {
typedef BSTNode Node;
typedef Node* PNode;
public:
BSTree()
:_pRoot(nullptr)
{}
~BSTree() {
_Distory(_pRoot);
}
PNode Find(const T& data) {
PNode pCur = _pRoot;
while (pCur) {
if (pCur->_data == data)
return _pRoot;
else if (pCur->_data < data)
pCur = _pRoot->_pLeft;
else if (pCur->_data > data)
pCur = _pRoot->_pRight;
}
return nullptr;
}
bool Insert(const T & data) {
//空树
if (_pRoot == nullptr) {
_pRoot = new Node(data);
return true;
}
//树不为空,找到位置
PNode pCur = _pRoot;
PNode pParent = nullptr;
while (pCur) {
pParent = pCur;
if (pCur->_data > data) {
pCur = pCur->_pLeft;
}
else if (pCur->_data < data) {
pCur = pCur->_pRight;
}
else {
return false;
}
}
//插入
pCur = new Node(data);
if (data < pParent->_data) {
pParent->_pLeft = pCur;
}
else {
pParent->_pRight = pCur;
}
return true;
}
bool Erase(const T & data) {
if (_pRoot == nullptr)
return false;
PNode pCur = _pRoot;
PNode pParent = nullptr;
//寻找该结点
while (pCur) {
if (pCur->_data > data) {
pParent = pCur;
pCur = pCur->_pLeft;
}
else if (pCur->_data < data) {
pParent = pCur;
pCur = pCur->_pRight;
}
else
break;
}
if (pCur == nullptr)
return false;
//结点找到后,分情况处理
//1、要删除的结点只有右孩子
//2、要删除的结点只有左孩子
//3、要删除的结点左右孩子都有
Node* pDelNode = pCur;
if (pCur->_pLeft == nullptr) {
if (pCur == _pRoot) {
_pRoot = pCur->_pRight;
}
else {
if (pCur == pParent->_pLeft) {
pParent->_pLeft = pCur->_pRight;
}
else {
pParent->_pRight = pCur->_pRight;
}
}
}
else if (pCur->_pRight == nullptr) {
if (pCur == _pRoot) {
_pRoot = pCur->_pLeft;
}
else {
if (pCur == pParent->_pRight) {
pParent->_pLeft = pCur->_pLeft;
}
else {
pParent->_pRight = pCur->_pLeft;
}
}
}
else {
//找到右侧最小的节点来替换,pRet一定没有左孩子!!
Node* pRet = pCur->_pRight;
pParent = pCur;
while (pRet->_pLeft) {
pParent = pRet;
pRet = pRet->_pLeft;
}
pCur->_data = pRet->_data;
//如果 pRet 是根结点直接删除
if (pRet == pParent->_pLeft) {
pParent->_pLeft = pRet->_pRight;
}
else {
pParent->_pRight = pRet->_pRight;
}
pDelNode = pRet;
}
delete pDelNode;
return true;
}
Node* FindMin(Node* pRoot) {
if (pRoot->_pLeft == nullptr)
return pRoot;
Node* pCur = pRoot;
while (pCur->_pLeft)
pCur = pCur->_pLeft;
return pCur;
}
//Node* FindMax(PNode pCur) {
// if (_pRoot == nullptr)
// return nullptr;
// pCur = _pRoot;
// while (pCur->_pRight)
// pCur = pCur->_pRight;
// return pCur;
//}
//前、中、后序遍历
void Preorder() {
_Postorder(_pRoot);
}
void Inorder() {
_Inorder(_pRoot);
}
void Postorder() {
_Postorder(_pRoot);
}
//前、中、后序遍历非递归
void PreorderNor() {
_PreorderNor(_pRoot);
}
void InorderNor() {
_InorderNor(_pRoot);
}
void PostorderNor() {
_PostorderNor(_pRoot);
}
//层序遍历
void LevelOrder() {
_LevelOrder(_pRoot);
}
private:
//前、中、后递归遍历
void _Preorder(PNode pRoot) {
if (pRoot == nullptr)
return;
printf("%s", pRoot->_data);
_Preorder(pRoot->_pLeft);
_Preorder(pRoot->_pRight);
}
void _Inorder(PNode pRoot) {
if (pRoot == nullptr)
return;
_Inorder(pRoot->_pLeft);
printf("%s", pRoot->_data);
_Inorder(pRoot->_pRight);
}
void _Postorder(PNode pRoot) {
if (pRoot == nullptr)
return;
_Postorder(pRoot->_pLeft);
_Postorder(pRoot->_pRight);
printf("%s", pRoot->_data);
}
//前、中、后非递归遍历
void _PreorderNor(PNode pRoot) {
stack s;
PNode pCur;
PNode pTop;
pCur = pRoot;
if (pCur == nullptr)
return;
while (!s.empty()) {
while (pCur != nullptr) {
printf("%s", pCur->_data);
s.push(pCur);
pCur = pCur->_pLeft;
}
pTop = s.top;
s.pop();
pCur = pTop->_pRight;
}
}
void _InorderNor(PNode pRoot) {
stack s;
PNode pCur;
pCur = pRoot;
if (pRoot == nullptr)
return;
while (!s.empty()) {
while (pCur != nullptr) {
s.push(pCur);
pCur = pCur->_pLeft;
}
pCur = s.top();
s.pop();
printf("%s", pCur->_data);
pCur = pCur->_pRight;
}
}
void _PostorderNor(PNode pRoot) {
stack s;
PNode pCur;
PNode pTop;
PNode pLast;
pCur == pRoot;
if (pCur == nullptr)
return;
while (!s.empty()) {
while (pCur != nullptr) {
s.push(pCur);
pCur = pCur->_pLeft;
}
pTop = s.top();
if (pTop->_pRight == nullptr || pTop->_pRight == pLast) {
s.pop();
printf("%s", pTop->_data);
pLast = pTop;
}
else {
pCur = pTop->_pRight;
}
}
}
//层序遍历
void _LevelOrder(PNode pRoot) {
queue q;
PNode* front;
if (pRoot == nullptr)
return;
q.push(pRoot);
while (!q.empty()) {
front = q.front();
q.pop();
if (front->_pLeft)
q.push(front->_pLeft);
if (front->_pRight)
q.push(front->_pRight);
printf("%s", front->_data);
}
}
private:
void _Distory(Node * pRoot) {
if (pRoot == nullptr)
return;
_Distory(pRoot->_pLeft);
_Distory(pRoot->_pRight);
delete pRoot;
pRoot = nullptr;
}
private:
PNode _pRoot;
};