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

广州高端品牌网站建设哪家公司好手机网站仿站教程

广州高端品牌网站建设哪家公司好,手机网站仿站教程,企业logo设计用什么软件,wordpress 留言 插件目录 二叉搜索树的概念 单个节点的结构 二叉搜索树的结构 中序遍历 插入 查找 删除 析构 拷贝构造 重载赋值运算符 二叉搜索树的概念 二叉搜索数也称为二叉排序数或者二叉查找树 二叉搜索树:一棵二叉树,可以为空;如果不为空&…

目录

二叉搜索树的概念

单个节点的结构

二叉搜索树的结构

中序遍历

插入

查找

删除

析构

拷贝构造

重载赋值运算符


二叉搜索树的概念

二叉搜索数也称为二叉排序数或者二叉查找树

二叉搜索树:一棵二叉树,可以为空;如果不为空,要满足以下性质

1. 非空左子树的所有键值小于其根节点的键值

2. 非空右子树的所有键值大于其根节点的键值

3. 左右子树都是二叉搜索树

特征:

这样的二叉搜索树通过中序遍历后是升序,因为左子树都小于根节点,右子树都大于根节点,所以也称之为二叉排序树 


单个节点的结构

struct BSTreeNode
{BSTreeNode(const K& key):_key(key),_left(nullptr),_right(nullptr){}K _key;BSTreeNode<K>* _left;BSTreeNode<K>* _right;
};

左子树的值要小于根节点的值,右子树的值要大于根节点的值 


二叉搜索树的结构

template<class K>
struct BSTree
{typedef BSTreeNode<K> Node;public:// 函数实现...private:Node* root = nullptr;
};

中序遍历

private:void _InOrder(Node* root){if (root == nullptr)return;// 左子树 - 根 - 右子树_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}public:void InOrder(){_InOrder(_root);cout << endl;}

因为在类外面不能访问私有变量 _root,所以在类里面实现递归时需要配合子函数来实现


插入

bool Insert(const K& key)
{// 判断二叉树是否为空,为空时直接插入链接if (_root == nullptr){_root = new Node(key);return true;}// 不为空时,需要找到合适的插入位置Node* parent = nullptr;Node* cur = _root;while (cur != nullptr){parent = cur;if (cur->_key < key){// 当前节点的值小于要插入的值,那么就往右节点走cur = cur->_right;}else if(cur->_key > key){// 否则就往左节点走cur = cur->_left;}else{// 相等时就结束return false;}}// 找到合适的位置时就链接cur = new Node(key);if (parent->_key > key){parent->_left = cur;}else{parent->_right = cur;}return true;
}

因为规定二叉搜索树不能出现一样的值,所有在判断是否相等时直接返回 false ,证明这个值已经存在了

parent 指针指向 cur 的前一个节点,方便最后 cur 找到合适的位置时链接,在链接时,parent 指向的节点也不知道 cur 该链接在左或是右,所以需要再次比较得出结果

测试代码:


查找

bool Find(const K& kay)
{Node* cur = _root;while (cur != nullptr){if (cur->_key > kay){// 当前节点大于 key 时就往左节点找cur = cur->_left;}else if (cur->_key < kay){// 当前节点小于 key 时就往左节点找cur = cur->_right;}else{// 相等就是找到了,返回 truereturn true;}}// 一直没有找到就返回 falsereturn false;
}

同样是根据左小右大的规则来查找


删除

bool Erase(const K& key)
{// 先找到要删除的节点Node* cur = _root;Node* parent = nullptr;while (cur != nullptr){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else{// 找到了,进行删除if (cur->_left == nullptr) //当要删除的节点左为空时{if (cur == _root){// 当要删除的节点为根节点时要单独处理_root = cur->_right;}else{if (cur == parent->_left){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}}else if (cur->_right == nullptr) //当要删除的节点右为空时{if (cur == _root){_root = cur->_left;}else{if (cur == parent->_left){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}}else //当要删除的节点左右都不为空时{// 先找到右树的最小节点(最左节点)Node* subLeft = cur->_right;Node* subParent = cur;while (subLeft->_left != nullptr){subLeft = subLeft->_left;}// 交换std::swap(cur->_key, subLeft->_key);// 链接if (subLeft == subParent->_left)subParent->_left = subLeft->_right;elsesubParent->_right = subLeft->_right;}// 删除完成,最后返回 truereturn true;}}// 没有找到要删除的节点return false;
}

如图所示:

先通过左小右大的原则来找要删除的节点,找到后开始删除

在删除的节点里面有三种情况:

1. 要删除的节点只有左子树没有右子树

2. 要删除的节点只有右子树没有左子树

3. 要删除的节点有左右子树

叶子节点可以归纳为1、2点内

那么先拿删除 14 节点举例:

那么 14 节点就是右子树为空,创建一个 parent 节点指针指向 14 节点的父亲,也就是 10 节点,并且直接判断 14 节点是 10 节点的左还是右,因为 14 节点的右为空,所以判断后 10 节点直接链接 14 节点的左即可

需要注意的是,当要删除的节点是根节点时,就是根节点的右或者左子树为空时,需要作特殊处理,详情请见代码

删除 10 节点,10 节点是左子树为空的情况也是一样的,这里就不过多赘述

删除叶子节点也和上面的代码逻辑一样

删除 8 节点举例:

8 节点既是根节点也是左右子树都不为空的情况,那么删除的话就需要使用交换法

找出左子树中最大的节点,或者找出右子树最小的节点进行交换,这样才能成功交换,并且不影响二叉树

以上代码中我实现的是找出右子树最小的节点进行交换,所以 subLeft 就是找到右子树中最小的那个节点,也就是最左边的那个节点,subParent 指向  subLeft 的父亲节点

然后 subLeft 和要删除的节点 cur 进行交换,交换后再通过 subParent 进行链接,因为 subLeft 是右子树的最左节点,所以 subLeft 一定没有左子树,所以只需要判断 subLeft 在 subParent 的左还是右,再通过 subParent 的左或者右链接 subLeft 的右即可


析构

private:void Destroy(Node*& root){// 后续递归if (root == nullptr){return;}// 左子树 - 右子树 - 根Destroy(root->_left);Destroy(root->_right);delete root;}public:~BSTree(){_~BSTree(_root);}

拷贝构造

private:Node* copy(Node* root){// 前序拷贝if (root == nullptr){return nullptr;}// 根 - 左子树 - 右子树Node* newRoot = new Node(root->_key);newRoot->_left = copy(root->_left);newRoot->_right = copy(root->_right);return newRoot;}public:BSTree(const BSTree<K>& t){_root = copy(t._root);}

重载赋值运算符

BSTree<K>& operator=(BSTree<K> t)
{swap(_root, t._root);return *this;
}

文章转载自:

http://5POxRXUr.ghxsn.cn
http://1cI3JH7P.ghxsn.cn
http://9paMWgS4.ghxsn.cn
http://s64Xpoxx.ghxsn.cn
http://zMmBSXKU.ghxsn.cn
http://zTBYo3OU.ghxsn.cn
http://HoWMpAMV.ghxsn.cn
http://IIkQj716.ghxsn.cn
http://3DhSXoAz.ghxsn.cn
http://wYNkREiK.ghxsn.cn
http://75hakhJe.ghxsn.cn
http://aX3DkBAz.ghxsn.cn
http://xpGuQaJO.ghxsn.cn
http://KE7dozW5.ghxsn.cn
http://wlFoqf3A.ghxsn.cn
http://hewVpe48.ghxsn.cn
http://p6uTjKUp.ghxsn.cn
http://xGqiYt0S.ghxsn.cn
http://cvLmslPW.ghxsn.cn
http://yZuXPno6.ghxsn.cn
http://a8hOVtsL.ghxsn.cn
http://JiqPkICz.ghxsn.cn
http://HTRPXsbF.ghxsn.cn
http://X0SQIuPS.ghxsn.cn
http://xEJP0zYa.ghxsn.cn
http://1i3IeQMX.ghxsn.cn
http://WbHKNHIi.ghxsn.cn
http://GYOoiDkg.ghxsn.cn
http://sTpK9agu.ghxsn.cn
http://TdjNHOrS.ghxsn.cn
http://www.dtcms.com/wzjs/683336.html

相关文章:

  • 品牌网站建设十小蝌蚪wordpress去除评论
  • gta5买房子网站建设创办一个公司需要什么条件
  • 深圳营销型网站建设+宝安西乡信德 网站建设
  • 零售网站建设wordpress替换主页
  • 分享类网站源码安溪网页定制
  • 萝岗微信网站建设做网站一个月可以赚多少钱
  • 新区快速seo排名青岛关键词推广seo
  • 深圳做手机网站建设定制做网站报价
  • 阿里云做网站多少钱找个网站2021能看到
  • 宁波高新区做网站的公司w3c验证网站
  • 会员型网站餐饮装修专业设计
  • 制作网页的网站fawordpress提示安装
  • 网站建设培训 通州网站的规划与建设
  • 做外贸兼职的网站小程序网站建设的公司
  • 上海做网站hlanggroup做的视频发到哪个网站好
  • 网站弹窗设计广西优化网站
  • 商城网站设计策划企业创新平台建设
  • 做原型网站秦皇岛咔咔科技有限公司
  • 需要做网站建设的行业有哪些单页建站系统
  • 做暧昧视频网站怎样找家做网站的公司
  • 做资源的教育类网站或公司沈阳京科医院男科
  • 湖南岳阳网站建设公司黄页顺企网如何做产品网站
  • 湖北建设网站首页wordpress yasaer
  • 帝国cms如何做网站学习软件开发的网站
  • 什么网站有做册子版附近广告公司喷绘刻字
  • 免费域名模板建站分割页面
  • 网站建设实验目的南昌企业建站程序
  • 网站设计的图片邯郸网站建设咨询安联网络
  • 巴彦淖尔网站制作中国职业培训在线官方网站
  • 深圳都信建设监理有限公司网站濮阳 网站建设