目录
1.binary_search_tree
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
namespace LRT {
template<class K, class V>
struct BSNode
{
BSNode<K, V>* _left;
BSNode<K, V>* _right;
K _key;
V _val;
BSNode()
:_left(nullptr),
_right(nullptr),
_key(0),
_val(0)
{}
BSNode(const K& key = 0, const V& val = 0)
:_left(nullptr),
_right(nullptr),
_key(key),
_val(val)
{}
};
template<class K, class V>
class binary_search_tree {
private:
BSNode<K, V>* _root;
typedef BSNode<K, V> node;
public:
binary_search_tree(void)
:_root(nullptr)
{
}
bool insert(const K& key, const V& val) {
return _insert(key, val, _root);
}
private:
bool _insert(const K& key, const V& val, node*& cur) { //传引用的得到的指针,直接修改指向,就是修改树上结点的连接2方式
if (cur == nullptr)
{
cur = new node(key, val);
return true;
}
if (key < cur->_key)
{
if (cur->_left == nullptr)
{
node* new_node = new node(key, val);
cur->_left = new_node;
return true;
}
return _insert(key, val, cur->_left);
}
if (key > cur->_key)
{
if (cur->_right == nullptr)
{
node* new_node = new node(key, val);
cur->_right = new_node;
return true;
}
return _insert(key, val, cur->_right);
}
if (key == cur->_key)
{
return false;
}
}
public:
void printf_bst(void) {
_printf_bst(_root);
}
private:
void _printf_bst(node* cur)
{
if (cur == nullptr)
{
return;
}
_printf_bst(cur->_left);
cout << cur->_key << " " << cur->_val << endl;
_printf_bst(cur->_right);
}
public:
node* find(const K& key) {
node* cur = _root;
while (cur) {
if (key < cur->_key) {
cur = cur->_left;
}
else if (key > cur->_key) {
cur = cur->_right;
}
else if(key == cur->_key) {//只写else的时候报了个内部编译的错误,可以一段段屏蔽,自己看看哪里有错误,毕竟这个报错报的一头雾水
return cur;
}
}
return nullptr;
}
bool erase_by_max_left(const K& key)//左树的最大节点除了根一定是其他节点的右子树
{
return _erase_by_max_left(_root, key);
}
private:
bool _erase_by_max_left(node*& cur, const K& key) {//此处必须传引用,因为要需修改当前节点
if (cur == nullptr) {
return false;
}
if(key<cur->_key){
return _erase_by_max_left(cur->_left,key);
}
else if (key > cur->_key) {
return _erase_by_max_left(cur->_right, key);
}
else {//找到了,开始准备删除
//如果左右字数有一颗为空,那么直接托孤
node* del = cur;//把原本正在维护的指向需要删除节点的的指针先拷贝一份,后面需要进行删除。
if (cur->_right == nullptr) {
cur = cur->_left;
}
else if (cur->_left == nullptr) {
cur = cur->_right;
}
else { //与其左子树最大值交换后递归下去删除该节点
node* max_left =cur->_left;//开始找该节点左子树的最大的节点
while (max_left->_right) {
max_left = max_left->_right;
}
swap(max_left->_key, cur->_key);
swap(max_left->_val, cur->_val);
return _erase_by_max_left(cur->_left, key);
}
delete del;
return true;
}
}
public:
bool erase_by_min_right(const K& key)
{
node* parent = nullptr;
node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else
{
// 1、左为空
if (cur->_left == nullptr)
{
if (cur == _root)//就是根的节点
{
_root = cur->_right;
}
else
{
if (parent->_left == cur)//要删除的节点是父亲的左还是右
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
delete cur;
} // 2、右为空
else if (cur->_right == nullptr)
{
if (cur == _root)//就是根的节点
{
_root = cur->_left;
}
else
{
if (parent->_left == cur)//要删除的节点是父亲的左还是右
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
}
delete cur;
}
else
{
// 找右树最小节点替代,或左树最大节点
node* parent_minRight = cur;
node* minRight = cur->_right;
while (minRight->_left)
{
parent_minRight = minRight;
minRight = minRight->_left;
}
cur->_key = minRight->_key;
if (parent_minRight->_left == minRight)
{
parent_minRight->_left = minRight->_right;
}
else
{
parent_minRight->_right = minRight->_right;
}
delete minRight;
}
return true;
}
}
return false;
}
};
}
2.测试函数
test.c
void test()
{
//LRT::BSNode<int, int>* root = nullptr;
LRT::binary_search_tree<int,int> BST;
BST.insert(-13, 1);
BST.insert(-11, 1);
BST.insert(-89, 1);
BST.insert(-32, 1);
BST.insert(-44, 1);
BST.insert(1, 1);
BST.insert(1, 1);
BST.insert(2, 1);
BST.insert(3, 1);
BST.insert(7, 1);
BST.insert(14, 1);
BST.insert(12, 1);
BST.insert(7, 1);
BST.printf_bst();
cout << endl;
//auto ret= BST.find(7);
//if (ret)
//{
// cout << ret->_key << " " << ret->_val << endl;
//}
//ret = BST.find(-44);
//if (ret)
//{
// cout << ret->_key << " " << ret->_val << endl;
//}
BST.erase_by_max_left(1);
BST.printf_bst();
cout << endl;
BST.erase_by_max_left(-89);
BST.printf_bst();
cout << endl;
}
void test2()
{
int arr[15] = { 1,2,4,6,-3,-78,65,98 ,- 40,33,23,-45,-6,-31,45 };
int arr2[15] = { 1,2,4,6,-3,-78,65,98 - 40,33,23,-45,-6,-31,45 };
LRT::binary_search_tree<int, int> BST;
for (int i = 0; i < 15; i++)
{
BST.insert(arr[i], arr[i]);
}
BST.printf_bst();
cout << endl;
//for (int i = 0; i < 15; i++)
//{
// BST.erase_by_max_left(arr[i]);
// BST.printf_bst();
// cout << endl;
//}
for (int i = 14; i >=0; i--)
{
BST.erase_by_max_left(arr[i]);
BST.printf_bst();
cout << endl;
}
cout << endl;
}
void test3() {
int arr[15] = { 1,2,4,6,-3,-78,65,98 ,-40,33,23,-45,-6,-31,45 };
int arr2[15] = { 1,2,4,6,-3,-78,65,98 - 40,33,23,-45,-6,-31,45 };
LRT::binary_search_tree<int, int> BST;
for (int i = 0; i < 15; i++)
{
BST.insert(arr[i], arr[i]);
}
BST.printf_bst();
cout << endl;
//for (int i = 0; i < 15; i++)
//{
// BST.erase_by_max_left(arr[i]);
// BST.printf_bst();
// cout << endl;
//}
for (int i = 14; i >= 0; i--)
{
BST.erase_by_min_right(arr[i]);
BST.printf_bst();
cout << endl;
}
cout << endl;
}
int main()
{
//test2();
test3();
}
3.判断一颗树是否是搜索二叉树
判断一棵二叉树是否为「二叉搜索树」的通用方法为:对该二叉树进行中序遍历,若遍历结果为「严格」单调递增的,则是一棵二叉搜索树,否则不是。