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

b2b网站发布信息网站推广优化方法

b2b网站发布信息,网站推广优化方法,网站怎么做图片转链,装修公司网站wordpress 模板序言: 构造一棵二叉排序树的目的并不是为了排序,而是为了提高查找效率、插入和删除关键字的速度,同时二叉搜索树的这种非线性结构也有利于插入和删除的实现。 目录 (一)BST的定义 (二)二叉搜…

序言:

构造一棵二叉排序树的目的并不是为了排序,而是为了提高查找效率、插入和删除关键字的速度,同时二叉搜索树的这种非线性结构也有利于插入和删除的实现。

二叉搜索树的表示及相关算法_雨纷飞-CSDN博客

目录

(一)BST的定义

(二)二叉搜索树操作

1、BST的查找

2、BST的插入

3、BST的删除

(三)二叉排序树的实现(非递归)

1、查找实现

2、插入实现

3、删除实现

(四)二叉排序树的实现(递归)

1、查找操作

2、插入操作

3、删除操作

(五)其他操作

1、析构

2、构造和拷贝构造

3、赋值重载

(六)总结


(一)BST的定义

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

  1. 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
  2. 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
  3. 它的左右子树也分别为二叉搜索树
     

(二)二叉搜索树操作

我以下图这棵二叉树为例,给大家进行有关二叉树操作的讲解:

1、BST的查找

思想:

  1. 二叉搜索树的查找是从根节点开始的,沿某个分支逐层的向下比较的过程;
  2. 若二叉排序树非空,先将给定值与根节点的关键字进行比较,若相等则查找成功;
  3. 若不等,如果小于根节点的关键字,则在根节点的左子树上进行查找;
  4. 否则,就在根节点的右侧进行查找。这显然是一个递归的过程!!

举例:

  1. 例如,对于上述二叉树我想要查找值为【6】的结点。
  2. 首先 6 与根节点 8 进行比较,由于 6<8 ,因此需要在根节点8的左子树中继续查找;
  3. 由于 3<6,因此在结点 3 的右子树中进行查找,最后查询成功。

2、BST的插入

二叉排序树作为一种动态树表,其特点是树的结构通常不是一次生成的,而是在查找过程中存在关键字值等于给定值的结点时再进行插入的。

插入结点的过程如下:

  1. 若原二叉排序树为空,则直接插入;
  2. 否则,若关键字 k 小于根结点值左子树;
  3. 若关键字 k 大于根结点值,则插入到右子树;

插入的结点一定是一个新添加且是查找失败时的查找路径上访问的最后一个结点的左孩子或右孩子。


3、BST的删除

在二叉排序树中删除一个结点时,不能把以该结点为根的子树上的结点都删除,必须先删除结点从存储二叉排序树的链表上摘下,将因删除结点而断开的二叉链表重新链接起来,确保二叉排序树的性质不会丢失。

首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情
况:

  • a.要删除的结点无孩子结点
  • b. 要删除的结点只有左孩子结点
  • c. 要删除的结点只有右孩子结点
  • d. 要删除的结点有左、右孩子结点
     

看起来有待删除节点有4中情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程
如下

  • 情况b:删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点--直接删除
  • 情况c:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点--直接删除
  • 情况d:在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,再来处理该结点的删除问题--替换法删除


(三)二叉排序树的实现(非递归)

1、查找实现

代码如下:

//查找操作bool Find(const K& key){Newnode* cur = _root;while (cur){if (cur->_key < key) {cur = cur->_right;}else if (cur->_key > key) {cur = cur->left;}else {return true;}}return false;}

2、插入实现

代码如下:

    //插入操作bool Insert(const K& key){if (_root == nullptr){_root = new Newnode(key);return true;}Newnode* parent = nullptr;Newnode* cur = _root;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{return false;}}//进行链接操作cur = new Newnode(key);if (parent->_key < key){parent->_right = cur;}else{parent->_left = cur;}return true;}

3、删除实现

代码如下:

//删除操作bool Erase(const K& key){Newnode* parent = nullptr;Newnode* cur = _root;while (cur){//存在左右结点的情况if (cur->_key < key) {parent = cur;cur = cur->_right;}else if (cur->_key > key) {parent = cur;cur = cur->_left;}else {//不存在左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;}//不存在右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 {// 找右树最小节点替代,也可以是左树最大节点替代Newnode* pminRight = cur;Newnode* minRight = cur->_right;while (minRight->_left){pminRight = minRight;minRight = minRight->_left;}cur->_key = minRight->_key;if (pminRight->_left == minRight) {pminRight->_left = minRight->_right;}else {pminRight->_right = minRight->_right;}delete minRight;}return true;}}return false;}

(四)二叉排序树的实现(递归)

递归实现都比较容易,只要大家掌握到了思想,我相信实现起来就是很容易的。

1、查找操作

    //查找操作bool _FindR(Newnode* root, const K& key){if (root == nullptr)return false;if (root->_key == key)return true;if (root->_key < key)return _FindR(root->_right, key);elsereturn _FindR(root->_left, key);}

2、插入操作

        //插入操作bool _InsertR(Newnode*& root, const K& key){if (root == nullptr) {root = new Newnode(key);//root = new BSTree<K>(key);return true;}if (root->_key < key) {return _InsertR(root->_right, key);}else if (root->_key > key) {return _InsertR(root->_left, key);}else {return false;}}

验证操作:

3、删除操作

        //删除操作bool _EraseR(Newnode*& root,const K& key){if (root == nullptr) {root = new Newnode(key);return true;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Newnode* del = root;if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{Newnode* maxleft = root->_left;while (maxleft->_left){maxleft = maxleft->_right;}swap(root->_key, maxleft->_key);return _EraseR(root->_left, key);}delete del;return true;}}

验证操作:


(五)其他操作

1、析构

析构同样的使用递归来进行解决(当然也可以使用循环)。具体如下

代码实现:

    //销毁操作void Destroy(Newnode*& root){if (root == nullptr)return;Destroy(root->_left);Destroy(root->_right);delete root;root = nullptr;}

2、构造和拷贝构造

首先如果我想在搜索二叉树的对象进行拷贝构造能够实现吗?具体如下:

 【说明】

  1. 我们发现是可以的,虽然我们没写;
  2. 这是因为拷贝构造属于默认成员函数,编译器会自动生成(注意;默认生成是属于浅拷贝)

【注意】 

  • 需要注意:当我们写了析构函数之后程序就会出问题;
  • 因为搜索二叉树涉及资源申请,如果是浅拷贝,在析构的时候就会对一块空间析构两次

所以此时就需要写一个深拷贝的拷贝构造函数(递归版本)

Newnode* Copy(Newnode* root)
{if (root == nullptr)return nullptr;Newnode* newRoot = new Newnode(root->_key);newRoot->_left = Copy(root->_left);newRoot->_right = Copy(root->_right);return newRoot;
}

 此时因为有了拷贝构造,编译器就不会生成默认的构造函数了,就需要我们自己写(C++11提供了一个关键字——default,可以强制编译器生成默认构造

BinarySearchTree() = default; // 制定强制生成默认构造

此时,它就会走初始列表用缺省值去初始化:

3、赋值重载

  • 最后实现一下赋值重载的操作:
BinarySearchTree<K>& operator=(BinarySearchTree<K> t)
{swap(_root, t._root);return *this;
}

代码演示:


代码总结

  • BSTree.h:
#pragma oncetemplate<class K>struct BSTree{BSTree<K>* _left;BSTree<K>* _right;K _key;BSTree(const K& key): _left(nullptr), _right(nullptr), _key(key){}};template<class K>class BinarySearchTree{typedef BSTree<K> Newnode;public:BinarySearchTree() = default; // 制定强制生成默认构造BinarySearchTree<K>& operator=(BinarySearchTree<K> t){swap(_root, t._root);return *this;}BinarySearchTree(const BinarySearchTree<K>& t){_root = Copy(t._root);}~BinarySearchTree(){Destroy(_root);}//插入操作bool Insert(const K& key){if (_root == nullptr){_root = new Newnode(key);return true;}Newnode* parent = nullptr;Newnode* cur = _root;while (cur){if (cur->_key < key) {parent = cur;cur = cur->_right;}else if (cur->_key > key) {parent = cur;cur = cur->_left;}else {return false;}}//进行链接操作cur = new Newnode(key);if (parent->_key < key){parent->_right = cur;}else{parent->_left = cur;}return true;}//查找操作bool Find(const K& key){Newnode* cur = _root;while (cur){if (cur->_key < key) {cur = cur->_right;}else if (cur->_key > key) {cur = cur->left;}else {return true;}}return false;}//删除操作bool Erase(const K& key){Newnode* parent = nullptr;Newnode* cur = _root;while (cur){//存在左右结点的情况if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else {//不存在左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;}//不存在右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 {// 找右树最小节点替代,也可以是左树最大节点替代Newnode* pminRight = cur;Newnode* minRight = cur->_right;while (minRight->_left){pminRight = minRight;minRight = minRight->_left;}cur->_key = minRight->_key;if (pminRight->_left == minRight) {pminRight->_left = minRight->_right;}else {pminRight->_right = minRight->_right;}delete minRight;}return true;}}return false;}///// 递归版本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);}void InOrder(){_Inorder(_root);cout << endl;}protected:Newnode* Copy(Newnode* root){if (root == nullptr)return nullptr;Newnode* newRoot = new Newnode(root->_key);newRoot->_left = Copy(root->_left);newRoot->_right = Copy(root->_right);return newRoot;}//销毁操作void Destroy(Newnode*& root){if (root == nullptr)return;Destroy(root->_left);Destroy(root->_right);delete root;root = nullptr;}//查找操作bool _FindR(Newnode* root, const K& key){if (root == nullptr)return false;if (root->_key == key)return true;if (root->_key < key)return _FindR(root->_right, key);elsereturn _FindR(root->_left, key);}//插入操作bool _InsertR(Newnode*& root, const K& key){if (root == nullptr) {root = new Newnode(key);return true;}if (root->_key < key) {return _InsertR(root->_right, key);}else if (root->_key > key) {return _InsertR(root->_left, key);}else {return false;}}//删除操作bool _EraseR(Newnode*& root, const K& key){if (root == nullptr) {root = new Newnode(key);return true;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Newnode* del = root;if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{Newnode* maxleft = root->_left;while (maxleft->_left){maxleft = maxleft->_right;}swap(root->_key, maxleft->_key);return _EraseR(root->_left, key);}delete del;return true;}}//中序遍历void _Inorder(Newnode* root){if (root == nullptr) {return;}_Inorder(root->_left);cout << root->_key << " ";_Inorder(root->_right);}private:Newnode* _root = nullptr;};

(六)总结

以上便是关于二叉搜索树的模拟实现。感谢大家的观看与支持!!!

http://www.khdw.cn/news/52478.html

相关文章:

  • 公司网站开发费账务处理seo优化推广教程
  • 彩票网站开发极云东莞营销网站建设直播
  • 网站建设公司中深圳网站优化培训
  • 做商城网站需要多大的服务器南宁seo全网营销
  • 泉州最专业微信网站建设开发百度软文推广公司
  • 大学什么专业做网站sem是什么岗位
  • 深圳装修公司招聘装修项目经理益阳网站seo
  • 网站别人做的我自己怎么续费seo是怎么优化的
  • 台州网站建设企业刷赞业务推广网站
  • 网站建设方案书填写示例百度竞价电话
  • 网站主机要多少钱semir
  • 网站做外链推广的常用方法推广怎么推
  • 微信网站建设哪家好2024年新冠疫情最新消息今天
  • 前端个人网站怎么做分享推广
  • 成都网站设计说明书推广网页怎么做的
  • 推荐企业手机网站建设泰州百度seo
  • 做系统网站信息检索网站技成培训网
  • 游戏网站建设方案百度推广登录入口官网
  • html5企业网站案例网站怎么提升关键词排名
  • 专做品牌的网站百度账户安全中心
  • web 网站模板seo如何优化的
  • 男男互做网站百度手机助手app下载官网
  • 邢台哪儿做网站便宜seo技术优化技巧
  • ip开源网站FPGA可以做点什么自己的网站怎么在百度上面推广
  • 网页制作工具按其制作方式分可以分为哪几种优化大师的使用方法
  • 什么网站可以做旅行行程英文seo是什么意思
  • 怎么建立微信网站域名注册管理机构
  • 广州购物网站建设报价爱站网站长seo综合查询
  • 做公众号需要网站贵港网站seo
  • 网站建设 太原免费培训课程