当前位置: 首页 > news >正文

二叉树进阶 之 【二叉搜索树的简介与模拟实现的前提准备】

目录

1.二叉搜索树的概念

2.实现的前提准备


1.二叉搜索树的概念

二叉搜索树又称二叉查找树或二叉排序树

或者是一棵空树或者具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树

二叉搜索树是递归定义的,最小子问题是空树

二叉搜索树主要有查找、插入、删除的功能,并且二叉树的中序遍历正好是数据的有序遍历

2.实现的前提准备

(1)文件与命名空间

创建一个BinarySearchTree.h文件来保存模拟实现的二叉搜索树

为了避免命名冲突,创建一个新的命名空间来封装模拟实现的二叉搜索树

(2)分类

与list实现相似,二叉搜索树实现需要两个类,

一个类管理单个树节点的定义、初始化等操作

另一个类管理不同树节点间的链接关系,继而实现相应功能

namespace dfq
{//管理单个的树节点template<class K>struct BSTreeNode{BSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;BSTreeNode(const K& key):_left(nullptr), _right(nullptr), _key(key){}};//管理不同的树节点template<class K>class BSTree{typedef BSTreeNode<K> Node;private:Node* _root;};
}

(1)通常将二叉搜索树节点的存储值叫作value,通过键值(key)的比较决定节点位置

从而有 K模型 KV模型 的说法,这里我们先讨论 K模型

(2)后续需频繁使用树节点,使用 struct 定义管理单个树节点的类

(3)树节点中需保存左右孩子指针及键值,再手写构造函数进行初始化

(4)只需要根节点就可以管理不同树节点间的链接关系

(3)默认成员函数

//构造函数
BSTree():_root(nullptr)
{ }//拷贝构造
BSTree(const BSTree<K>& t)
{//改变根节点_root = Copy(t._root);
}Node* Copy(Node* root)
{if (!root)return nullptr;Node* copyroot = new Node(root->_key);copyroot->_left = Copy(root->_left);copyroot->_right = Copy(root->_right);return copyroot;
}

(1)拷贝构造创建的树只是树节点键值、连接关系与传入对象相同,为防止内存的重复释放需要进行深拷贝

(1)拷贝构造的重点是递归的使用(使用前序遍历,访问当前树的根节点时即进行拷贝操作)

(2)另起一个Copy函数,最小子问题是空树

如果根节点为空,返回值为nullptr,否则,

先创建一个新的树节点拷贝当前树的根节点的键值,

再递归调用函数完成不同节点间的链接关系

当递归到空树时,函数开始返回,不同树节点的链接开始....

//析构函数
~BSTree()
{//传入根节点,后续遍历删除Destroy(_root);
}void Destroy(Node*& root)
{if (!root)return;Destroy(root->_left);Destroy(root->_right);delete root;root = nullptr;
}

(1)使用后序遍历的思想(减少临时保存的操作)销毁一棵二叉搜索树

因为析构函数不能传参,这里调用子函数进行销毁

(2)传入节点指针的引用,可在销毁树节点的同时置空该指针

(3)最小子问题是空树,树为空就返回,否则

先销毁左子树,再销毁右子树,最后销毁根节点

(1)红色的线代表向下递归,直到树为空时开始自底向上销毁

//复制重载
BSTree<K, V>& operator=(BSTree<K, V> t)
{swap(_root, t._root);return *this;
}

赋值重载的简洁之处在于,传值传参就可完成深拷贝(默认拷贝构造正确实现)

此时只需交换两棵树的根节点即可

知道了一棵二叉搜索树的根节点,“树藤摸瓜”,即可访问整棵树,

所以我们可以说,根节点就是一棵树的代表

我们使用根节点管理一棵树,那么交换两棵树的根节点就是在交换两棵树

http://www.dtcms.com/a/324960.html

相关文章:

  • 【杂谈】-智能代理+可观察性:构建下一代复杂系统监控体系
  • UE5多人MOBA+GAS 41、制作一个飞弹,添加准心索敌
  • JS实现数组扁平化
  • 计算二分类误差时的常见错误及解决方案
  • ubuntu22.04+samba
  • VMware 使用 Ubuntu 一段时间后逐渐卡顿、甚至卡死的问题
  • sqli-labs-master/Less-51~Less-61
  • 解读 GPT-5:从“博士级 AI 专家”能力到 OpenAI API Key 获取与实践(提示工程→性能调优全流程)
  • MySQL自增ID与UUID的区别及其在索引分裂中的表现与优化
  • W3D引擎游戏开发----从入门到精通【23】
  • 2013年考研数学(二)真题
  • A#语言详解
  • 相比于传统的全波分析,特征模分析具有哪些优点
  • vue如何监听localstorage
  • 博览会(树形DP)
  • 机器学习——标准化、归一化
  • Spring Boot 事务详解:原理与实操指南
  • AQS(AbstractQueuedSynchronizer)底层源码实现与设计思想
  • 第三章-提示词:从0到1,提示词实训全攻略,解锁大语言模型无限潜能(14/36)
  • MyBatis Mapper核心组件协作关系深度解析
  • Java条件判断与用户交互实战案例
  • 【经典算法】二叉树最小深度详解:递归解法与可视化分析
  • 深入解析C#并行编程:从并行循环到异步编程模式
  • PyCATIA深度解析:基于装配截面自动化创建参考几何平面群的专业方案
  • 锂电生产设备健康管理:基于预测性维护的智能化解决方案​
  • 【github.io静态网页 怎么使用 github.io 搭建一个简单的网页?】
  • Python与MySQL数据库交互实践:自动化数据插入系统
  • GPU版的Pytorch安装(Win11)
  • SpringBoot项目自定义静态资源映射规则
  • 【嵌入式】Linux的常用操作命令 (1)