BST,要么是空树,要么具有以下性质:
二叉排序树(BST)(二叉搜索树)
1.要么是空树,要么有下面性质
2.左子树如果不空,左子树上所有节点的值都小于根节点
3.右子树如果不空,右子树上所有节点的值都大于根节点
4.左右子树分别又是BST
5.按照中序遍历,是从小到大排好序的
6.最左边的孩子一定是最小的节点
7.最右边的孩子一定是最大的节点
注意:有可能有重复的
class BSTNode
{
public:
BSTNode():m_left(nullptr),m_right(nullptr){}
BSTNode(int v) :m_value(v), m_left(nullptr), m_right(nullptr) {}
int m_value;
BSTNode* m_left;
BSTNode* m_right;
};
class BSTree
{
public:
BSTree():m_root(nullptr){}
void InsertValueBST(int v)
{
InsertValueBST(m_root, v);
}
void InsertValueBST(BSTNode*& m_root, int v);
void Print()//打印调中序遍历
{
InOrder(m_root);
cout << endl;
}
void InOrder(BSTNode* root);//中序遍历
BSTNode* SearchValue(int v)//查找该值,返回节点
{
return SearchValue(m_root, v);
}
BSTNode* SearchValue(BSTNode* root, int v);
BSTNode* GetMin();//最左边的孩子
BSTNode* GetMax();//最右边的孩子
void DeleValue(int k)//重点是删除
{
DeleValue(m_root, k);
}
void DeleValue(BSTNode*& root, int k);
private:
BSTNode* m_root;
};
void BSTree::InsertValueBST(BSTNode*& m_root, int v)
{
if (m_root == nullptr)
{
m_root = new BSTNode(v);
}
else if (v < m_root->m_value)
{
InsertValueBST(m_root->m_left, v);
}
else if (v > m_root->m_value)
{
InsertValueBST(m_root->m_right, v);
}
}
void BSTree::InOrder(BSTNode* root)
{
if (root != nullptr)
{
InOrder(root->m_left);
cout << root->m_value << " ";
InOrder(root->m_right);
}
}
BSTNode* BSTree::SearchValue(BSTNode* root, int v)
{
if (root == nullptr)
return nullptr;
else if (v > root->m_value)//大于根节点的值在右子树找
{
return SearchValue(root->m_right, v);
}
else if (v < root->m_value)//小于根节点的值在左子树找
{
return SearchValue(root->m_left, v);
}
else
return root;
}
BSTNode* BSTree::GetMin()
{
BSTNode* p = m_root;
if (p != nullptr)
{
while (p->m_left != nullptr)
{
p = p->m_left;
}
}
return p;
}
BSTNode* BSTree::GetMax()
{
BSTNode* p = m_root;
if (p != nullptr)
{
while (p->m_right != nullptr)
{
p = p->m_right;
}
}
return p;
}
void BSTree::DeleValue(BSTNode*& root, int k)
{
BSTNode* temp = nullptr;
if (root != nullptr)
{
//找
if (k < root->m_value)
{
DeleValue(root->m_left, k);
}
else if (k > root->m_value)
{
DeleValue(root->m_right, k);
}
//有两个孩子
else if (root->m_left != nullptr && root->m_right != nullptr)
{
/*
观察发现:要删除的节点的前驱是第一个左孩子的最右边孩子,后继是第一个右孩子的最左侧
孩子,则用其中一个去替换要删除的节点,然后删除替换的那个节点
(用它的前驱把它盖住或者用它的后继把它盖住都是可以的)
*/
//找右最左
temp = root->m_right;
while (temp->m_left != nullptr)
{
temp = temp->m_left;
}
root->m_value = temp->m_value;
DeleValue(root->m_right, root->m_value);//右子树找到它,并删掉它
}
//有一个孩子或没有孩子,直接删
else
{
temp = root;
if (root->m_left == nullptr)
root = root->m_right;
else if (root->m_right == nullptr)
root = root->m_left;
delete temp;
temp = nullptr;
}
}
}
void main()
{
int num[] = { 62,88,58,47,35,73,51,99,37,93 };
int n = sizeof(num) / sizeof(num[0]);
BSTree bhk;
for (int i = 0; i < n; i++)
{
bhk.InsertValueBST(num[i]);
}
bhk.Print();
BSTNode* p = bhk.SearchValue(62);
if (p == nullptr)
{
cout << "没找到" << endl;
}
else
{
cout << "找到了 " << p->m_value << endl;
}
if (p = bhk.GetMax())
{
cout << "max = " << p->m_value << endl;
}
if (p = bhk.GetMin())
{
cout << "min = " << p->m_value << endl;
}
bhk.DeleValue(88);
bhk.Print();
}