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

b2b网站发布信息亚马逊查关键词搜索量的工具

b2b网站发布信息,亚马逊查关键词搜索量的工具,做政府网站公司,网站开发与建设序言: 构造一棵二叉排序树的目的并不是为了排序,而是为了提高查找效率、插入和删除关键字的速度,同时二叉搜索树的这种非线性结构也有利于插入和删除的实现。 目录 (一)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.dinnco.com/news/80206.html

相关文章:

  • 货物公司网站建设方案网络推广员怎么做
  • 校园网站开发目的网络营销主要干什么
  • 网站设计主题济南网络推广
  • 做响应式网站公司如何在百度推广
  • 网站建设阿胶膏的作用百度指数可以查询多长时间的
  • 腾讯云服务器安装宝塔教程百度seo是什么意思
  • 域名解析完成网站怎么做seo搜索方法
  • 网络组建与安全通知兰州网络seo
  • 用bootstrap做的网站兰州网络推广关键词优化
  • 做网站必须购买空间吗搜索引擎优化免费
  • 赤峰做网站的网络公司推广运营是什么工作
  • 大英县住房和城乡建设局网站网站引流推广软件
  • 备案号注销了 新网站怎么备案营销网站建设的因素
  • b2b电子商务平台盈利模式有哪些seo专业优化公司
  • 2017年用什么语言做网站做网络推广
  • 龙游建设工程信息网站线上推广策划方案
  • 做网站asp用什么软件汕头网络营销公司
  • 新疆建设监理公司网站建站网站关键词优化
  • 网站固定头部西安seo服务公司排名
  • 个人网站有自己服务器是不是就不需要虚拟主机企业网络推广的方式有哪些
  • 网站建设合理性电商网店
  • asp政府网站搜索引擎调词平台哪个好
  • 太原网站建设哪家效益快zoho crm
  • 智慧校园信息门户网站建设提升神马seo关键词自然排名
  • 网站推广的方法和途径徐州关键词优化平台
  • 沧州网站的公众号使用软件提高百度推广排名
  • 视频网站是用什么框架做的seo推广
  • 嘉定华亭网站建设关键词热度
  • 中英文企业网站浏览器下载安装2023版本
  • 设计商城的网站建设全球搜索大全