二叉搜索树
作为一种二叉树类型的数据结构,掌握期性质是首要.
总的说就是,以某结点为视角,其左子树均为小于该结点值的结点,而右子树相反,且无重复值的结点.
性质:去重性,有序性.
自主实现
构造逻辑:但凡实现某功能,作为程序员,既要站在底层的角度,也要多从用户角度去考虑;
这是个二叉树数据结构,对其访问,用户仅需声明对应的类,然后调用对应的功能接口,
那我们就应这样思考,首先这主角对象应构建出来,即对结点进行创建,他包含什么成员变量,可以或应该提供什么接口,在这仅需描述出具体对象即可,接口不需要
接下来是对是操作方面的构建,对着结点,以怎样的数据结构管理,因该或可以提供什么接口,
这是对操作的封装,站在用户角度更佳.
对一个任务的具体分析,在分解至较小步骤,这样不至于不知怎么着手
1.单值数据成员
明确结构:1.一个含模板Node类描述结点,包括成员变量指针,数据成员,构造函数初始化;
2.一个BinarySearchTree类,提供二叉搜索树的功能接口,插入,删除,查找,判断(可补充 求高度,结点个数);
知识点:对链表的结点操作(增删查改),指针运用,递归的运用(前,中序遍历,如何通过递归返回需求值).体会类和对象的封装性,面相对象.
收获:为什么递归要封装一层函数(提供给用户接口,封装性),搜索树的拷贝需要深拷贝,
BSTree() =default;禁止生成默认构造函数-为什么,有什么意义:a.强制初始化,b.避免产生无意义的对象,c.强制采用特定的构造方式. 本例子中,创造没有根结点的二叉树是无意义的
2.双值数据成员
目的:为后续键值对数据类型的学习做铺垫
大致内容相似,就数据成员的改动.
3.实现代码
#pragma once
#include<iostream>
#include<cassert>
//命名空间
namespace key
{
//结点的构建
template<class K>
struct BSTreeNode
{
typedef BSTreeNode<K> Node;
Node* _left;
Node* _right;
K _key;
BSTreeNode(const K key)
:_left(nullptr), _right(nullptr), _key(key)
{
}
};
//二叉搜索树的接口实现--因为提供给用户,无法访问私有成员,所以在需要根节点是,封装一层函数
template<class K>
class BSTree
{
typedef BSTreeNode<K> Node;
public:
BSTree() =default;
BSTree(const BSTree<K>& t)
{
_root = Copy(t._root);//?
}
void swap(Node* &p1, Node* &p2)
{
p1 = deepCopyTree(p2);
}
BSTree <K>& operator=( BSTree<K> &t)
{
swap(_root,t._root);
return *this;
}
~BSTree()
{
Destroy(_root);
}
bool Find(const K key)
{
if (nullptr == _root)
{
return false;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else
{
return true;
}
}
return false;
}
bool Insert(const K key)
{
if (nullptr == _root)
{
//Node newNode = new Node(key);
//_root = &newNode;
_root = new Node(key);
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
cur = new Node(key);
if (key < parent->_key)
{
parent->_left = cur;;
}
else
{
parent->_right = cur;
}
return true;
}
bool Erase(const K key)
{
if (nullptr == _root)
{
return false;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else
{
if (cur == _root)
{
delete cur;
_root = nullptr;
}
if (cur->_left == nullptr)
{
if (cur == _root)
{
_root = cur->_right;
delete cur;
return true;
}
if (cur == parent->_left)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
delete cur;
return true;
}
else if (cur->_right == nullptr)
{
if (cur == _root)
{
_root = cur->_left;
delete cur;
return true;
}
if (cur == parent->_left)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
delete cur;
return true;
}
else
{
Node* LeftMaxParent = cur;
Node* LeftMax = cur->_left;
while (LeftMax->_right)
{
LeftMaxParent = LeftMax;
LeftMax = LeftMax->_right;
}
cur->_key = LeftMax->_key;
if (LeftMax == LeftMaxParent->_left)
{
LeftMaxParent->_left = LeftMax->_left;
}
else
{
LeftMaxParent->_right = LeftMax->_left;
}
delete LeftMax;
return true;
}
}
}
return false;
}
void Inorder()
{
return _Inorder(this->_root);
}
/*---------------------------------------------------------*/
bool FindR(const K& key)
{
return _FindR(_root,key);
}
bool InsertR(const K& key)
{
return _InsertR(_root, key);
}
bool EraseR(const K& key)
{
return _EraseR(_root, key);
}
private:
bool _FindR(Node* root, const K& key)
{
if (root == nullptr)
{
return false;
}
if (key < root->_key)
{
return _FindR(root->_left,key);
}
else if (key > root->_key)
{
return _FindR(root->_right, key);
}
else
{
return true;
}
}
bool _InsertR(Node*& root, const K& key)
{
if (root == nullptr)
{
root = new Node(key);
return true;
}
if (key < root->_key)
{
return _InsertR(root->_left, key);
}
else if (key > root->_key)
{
return _InsertR(root->_right, key);
}
else
{
return false;
}
}
bool _EraseR(Node*& root, const K& key)
{
if (root == nullptr)
{
return false;
}
if (key < root->_key)
{
return _EraseR(root->_left, key);
}
else if (key > root->_key)
{
return _EraseR(root->_right, key);
}
else
{
if (root->_left == nullptr)
{
Node* tmp = root;
root = root->_right;
delete tmp;
return true;
}
else if (root->_right == nullptr)
{
Node* tmp = root;
root = root->_left;
delete tmp;
return true;
}
else
{
Node* LeftMaxParent = root;
Node* LeftMax = root->_left;
while (LeftMax->_right)
{
LeftMaxParent = LeftMax;
LeftMax = LeftMax->_right;
}
root->_key = LeftMax->_key;
if (LeftMax == LeftMaxParent->_left)
{
LeftMaxParent->_left = LeftMax->_left;
}
else
{
LeftMaxParent->_right = LeftMax->_left;
}
delete LeftMax;
return true;
}
}
}
private:
Node* deepCopyTree(const Node* root) {
if (root == nullptr) {
return nullptr;
}
// 创建当前节点的拷贝
Node* newNode = new Node(root->_key);
// 递归拷贝左子树和右子树
newNode->_left = deepCopyTree(root->_left);
newNode->_right = deepCopyTree(root->_right);
return newNode;
}
void Destroy(const Node* root)
{
if (root == nullptr) return;
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
Node* Copy(const Node* root)
{
/*Node* newRoot = new Node(root->_key);
newRoot->_left = root->_left;
newRoot->_right = root->_right;
return newRoot;*/
return deepCopyTree(root);
}
void _Inorder(const Node* root)
{
if (root == nullptr)
{
return;
}
_Inorder(root->_left);
std::cout << root->_key << " ";
_Inorder(root->_right);
}
private:
Node* _root = nullptr;
};
}
//体会双值的区别,为键值对做铺垫
namespace key_value
{
template<class K,class V>
struct BSTreeNode
{
typedef BSTreeNode<K,V> Node;
Node* _left;
Node* _right;
K _key;
V _value;
BSTreeNode(const K key,const V value)
:_left(nullptr), _right(nullptr), _key(key), _value(value)
{
}
};
template<class K,class V>
class BSTree
{
typedef BSTreeNode<K,V> Node;
public:
bool Find(const K key)
{
if (nullptr == _root)
{
return false;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else
{
return true;
}
}
return false;
}
bool Insert(const K key,const V value)
{
if (nullptr == _root)
{
//Node newNode = new Node(key);
//_root = &newNode;
_root = new Node(key, value);
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
cur = new Node(key, value);
if (key < parent->_key)
{
parent->_left = cur;;
}
else
{
parent->_right = cur;
}
return true;
}
bool Erase(const K key)
{
if (nullptr == _root)
{
return false;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else
{
if (cur == _root)
{
delete cur;
_root = nullptr;
}
if (cur->_left == nullptr)
{
if (cur == _root)
{
_root = cur->_right;
delete cur;
return true;
}
if (cur == parent->_left)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
delete cur;
return true;
}
else if (cur->_right == nullptr)
{
if (cur == _root)
{
_root = cur->_left;
delete cur;
return true;
}
if (cur == parent->_left)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
delete cur;
return true;
}
else
{
Node* LeftMaxParent = cur;
Node* LeftMax = cur->_left;
while (LeftMax->_right)
{
LeftMaxParent = LeftMax;
LeftMax = LeftMax->_right;
}
cur->_key = LeftMax->_key;
if (LeftMax == LeftMaxParent->_left)
{
LeftMaxParent->_left = LeftMax->_left;
}
else
{
LeftMaxParent->_right = LeftMax->_left;
}
delete LeftMax;
return true;
}
}
}
return false;
}
void Inorder()
{
return _InOrder(this->_root);
std::cout << std::endl;
}
private:
void _InOrder(Node* root)
{
if (root == nullptr)
return;
_InOrder(root->_left);
std::cout << root->_key << " "<<root->_value<<" "<<std::endl;
_InOrder(root->_right);
}
private:
Node* _root = nullptr;
};
}
标签:黑树,Node,return,cur,key,left,root,撕红
From: https://blog.csdn.net/2303_76993116/article/details/140397088