//BST:Binary Search Tree
//根节点左子树 < 根 < 根节点右子树
//对BST进行中序遍历得到升序序列
#include<iostream>
using namespace std;
#include<vector>
template < class T>
class BSTNode
{
public:
BSTNode(const T& data = T())
:_left(nullptr)
, _right(nullptr)//构造结点时就对结点的左右孩子进行nullptr初始化
, _data(data)
{}
BSTNode<T>* _left;
BSTNode<T>* _right;
T _data;
};
template<class T>
class BSTree
{
typedef BSTNode<T> Node;
public:
BSTree()
:_root(nullptr)
{}
~BSTree()
{
_DestoryBSTree(_root);
}
bool insert(T data)
{
if (nullptr == _root)
{
_root = new Node(data);
return true;
}
Node* node = _root;
while (node)
{
if (data == node->_data)
return true;
if (data < node->_data)
{
if (node->_left == nullptr)
{
node->_left = new Node(data);
return true;
}
else
node = node->_left;
}
else if (data > node->_data)
{
if (node->_right == nullptr)
{
node->_right = new Node(data);
return true;
}
else
node = node->_right;
}
}
}
Node* find(T key)
{
Node* node = _root;
while (node)
{
if (node->_data == key)
return node;
else if (node->_data > key)
node = node->_left;
else node = node->_right;
}
return nullptr;
}
vector<int> inorder()//中序遍历
{
vector<T> res;
_inorder(_root, res);
return res;
}
bool Erase(const T& data)
{
if (nullptr == _root)
return false;
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
if (data == cur->_data)
break;
else if (data < cur->_data)
{
parent = cur;
cur = cur->_left;
}
else
{
parent = cur;
cur = cur->_right;
}
}
if (nullptr == cur)//cur为空说明,是while循环退出,不是break退出
return false;
/*找到结点,删除结点有三种情况:
1.只有根节点,或是叶节点
2.只有左子树或右子树
3.左右子树都有
*/
Node* del = cur;
if (!cur->_left && !cur->_right)//要删除的结点为叶节点,或是这个树只有一个根
{
if (parent->_left == cur)//是父节点的左孩子,把父节点左支置空
parent->_left = nullptr;
else parent->_right = nullptr;
delete cur;
return true;
}
if (cur->_left == nullptr && cur->_right)//只有右孩子
{
if (nullptr == parent)//要删结点为根
{
_root = cur->_right;
}
else
{
if (cur == parent->_left)//用父节点的左指针链接要删节点的右子树
parent->_left = cur->_right;
else
parent->_right = cur->_right;
}
}
else if (nullptr == cur->_right && cur->_left)//只有左孩子
{
if (nullptr == parent)
{
_root = cur->_left;
}
else
{
if (cur == parent->_left)
parent->_left = cur->_left;
else
parent->_right = cur->_left;
}
}
else//左右孩子都有
/*要么和左子树的最大结点或右子树的最小节点交换
并且找到的要交换节点必是叶子结点
因为对于左子树最大的要么是根(有孩子)要么是右叶子,而是根的情况已经在上面排除,这里
*/
{
Node* del = cur->_right;
while (del->_left)
{
parent = del;
del = del->_left;
}
cur->_data = del->_data;
if (del == parent->_left)
parent->_left = del->_right;
else
parent->_right = del->_right;
}
delete del;
return true;
}
private:
void _inorder(Node* node, vector<T>& res)
{
if (node)
{
_inorder(node->_left, res);
res.push_back(node->_data);
_inorder(node->_right, res);
}
}
void _DestoryBSTree(Node*& root)//析构调用
{
if (root)
{
_DestoryBSTree(root->_left);
_DestoryBSTree(root->_right);
delete root;
root = nullptr;
}
}
private:
BSTNode<T>* _root;
};
/*
find(int key)
while (cur)
if (key == cur->data)
return cur;
else if (key < cur->data)
cur = cur->left;
else cur = cur->right;
*/
void test01()
{
BSTree<int> bst1;
vector<int> values = { 1, 23, 4, 1, 1, 2, 2, 6, 54, 5, 14, 98 };
for (auto x : values)
bst1.insert(x);
auto v = bst1.inorder();
for (auto x : v)
cout << x << " ";
cout << endl;
if (bst1.find(100))
cout << "存在" << endl;
else cout << "不存在" << endl;
int key;
cout << "输入要删除的数据" << endl;
//cin >> key;
bst1.Erase(2);
v = bst1.inorder();
for (auto x : v)
cout << x << " ";
}
int main()
{
test01();
_CrtDumpMemoryLeaks();
return 0;
}
二叉排序树的中序遍历结果总是有序的,每个相同结点只存储一次,增删元素后要仍保证二叉排序树的特性(左 < 根 < 右),改(删+增),查找(效率很高,就像二分搜索),删除操作要注意对各种不同情况的del节点处理,析构函数通过递归delete结点,先删左右再删根。