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

北京网站设计公司哪儿济南兴田德润简介百度人工投诉电话是多少

北京网站设计公司哪儿济南兴田德润简介,百度人工投诉电话是多少,做网站地图的步骤,网页素材网站免费个人主页:🍝在肯德基吃麻辣烫 我的gitee:C仓库 个人专栏:C专栏 文章目录 一、二叉搜索树的Insert操作(非递归)分析过程代码求解 二、二叉搜索树的Erase操作(非递归)分析过程代码求解…

在这里插入图片描述
在这里插入图片描述

个人主页:🍝在肯德基吃麻辣烫
我的gitee:C++仓库
个人专栏:C++专栏

文章目录

  • 一、二叉搜索树的Insert操作(非递归)
    • 分析过程
    • 代码求解
  • 二、二叉搜索树的Erase操作(非递归)
    • 分析过程
    • 代码求解
  • 三、二叉搜索树的Find操作
    • 代码求解
  • 四、构造+拷贝构造+析构+赋值重载
    • 节点的代码
    • 构造函数
    • 拷贝构造函数
    • 赋值运算符重载
    • 析构函数
  • 二叉搜索树递归版本
    • 插入操作递归版本
    • 删除操作递归版本
  • 总结



一、二叉搜索树的Insert操作(非递归)

分析过程

假如这里有一棵树,我们需要对这棵树插入一个新的节点:

在这里插入图片描述

  • 假如需要插入16这个节点。

在这里插入图片描述
要分几个步骤进行:
1)先从根节点开始判断待插入节点和根节点谁大,根节点大就往左比较,根节点小了就往右比较。

第一步这个过程需要提前记录节点的父亲。

2)找到待插入位置后,先new一个新的节点;然后判断该节点是在前面记录的父亲节点的左边还是右边,然后连接起来即可。

代码求解

bool _Insert(Node* root, const T& val)
{if (root == nullptr){root = new Node(val);return true;}Node* cur = _root;Node* cur_par = _root;//找插入位置while (cur){if (val > cur->_val){cur_par = cur;cur = cur->_right;}else if (val < cur->_val){cur_par = cur;cur = cur->_left;}//相同就不能插入else{cout << "无法插入" << endl;return false;}}//找到插入位置了,记录父亲Node* insNode = new Node(val);if (cur_par->_val < val){cur_par->_right = insNode;return true;}else{cur_par->_left = insNode;return true;}
}

二、二叉搜索树的Erase操作(非递归)

分析过程

以下面这棵树为例:

假如我们要删除7这个节点。
在这里插入图片描述

1)查找该节点是否存在于树中。

2)如果存在,先判断该节点属于下面的哪种类型:

  • 1)删除的节点是叶子节点,直接删除即可。
  • 2)删除的节点只有一个孩子,需要先判断它的孩子是left还是right,然后让该节点的父亲节点指向它的孩子即可。
  • 3)如果删除的节点有leftright两个孩子,需要找一个节点进行替换;来保证这棵树在删除一个节点后还是一棵二叉搜索树。该找哪个节点来替换呢?
    • 1)找删除节点的左子树的最大节点(最右)
    • 2)找删除节点的右子树的最小节点(最左)

找这两个节点的任意一个均可。

在这里可能有个疑问,万一找不到呢?

你放心吧!一定能找到,这是二叉搜索树的特性。

找到该节点后,将该节点与待删除的节点进行交换,然后删除交换后的节点即可。

在上面的例子中,很显然7属于叶子节点,直接删除即可。

需要注意的是:
我们在寻找那个替代节点时,像插入一样,需要记录它的父
亲,这样在删除的时候才能知道删除left孩子还是right孩子。

代码求解

bool _Erase(Node* root,const T& val)
{//第一步:先找到要删除的节点Node* cur = root;Node* cur_parent = cur;while (cur){if (cur->_val > val){cur_parent = cur;cur = cur->_left;}else if (cur->_val < val){cur_parent = cur;cur = cur->_right;}//找到了//待删除的节点分三种情况else{//1.左右子树为空;2.其中一个子树为空if (cur->_left == nullptr){//要知道我是父亲的左还是右if (cur_parent->_left == cur){cur_parent->_left = cur->_right;}else if (cur_parent->_right == cur){cur_parent->_right = cur->_right;}}else if (cur->_right == nullptr){//要知道我是父亲的左还是右if (cur_parent->_left == cur){cur_parent->_left = cur->_left;}else if (cur_parent->_right == cur){cur_parent->_right = cur->_left;}}//3.删除的节点左右都不为空else{//先找替代节点//找左子树的最大节点或者右子树的最小节点来替代//         最右             最左Node* lParent = cur;Node* leftMax = cur->_left;while (leftMax->_right){lParent = leftMax;leftMax = leftMax->_right;}//找到了,进行替换swap(cur->_val, leftMax->_val);//替换完成后,必须删除该节点,不能用递归删除。//因为如果用递归,可能就找不到要删除的节点了//这里还要判断leftMax这个替换节点是它父亲的左还是右子节点//因为有一种极端情况是,leftMax是在父亲的左边if (lParent->_right == leftMax){lParent->_right = leftMax->_left;//leftMax是左子树的最右节点了,它不会有右孩子,但可能有左孩子}else if (lParent->_left == leftMax){lParent->_left = leftMax->_left;}cur = leftMax;}delete cur;cur = nullptr;return true;}}return false;
}

三、二叉搜索树的Find操作

查找节点过于简单,直接贴代码。

代码求解

bool _Find(Node* root, const T& val)
{if (root == nullptr){return false;}Node* cur = _root;while (cur){if (cur->_val < val){cur = cur->_right;}else if (cur->_val > val){cur = cur->_left;}else{return true;}}return false;
}

四、构造+拷贝构造+析构+赋值重载

节点的代码

template<class T>
struct BSTreeNode
{BSTreeNode(const T& val):_left(nullptr), _right(nullptr), _val(val){}BSTreeNode<T>* _left;BSTreeNode<T>* _right;T _val;
};

构造函数

BSTree():_root(nullptr)
{}

拷贝构造函数

拷贝构造就是将一棵已有的树对每一个节点进行拷贝即可。
这个过程是深拷贝。

由于我们需要将每一个节点都进行拷贝并连接起来。所以这里需要前序遍历的思想处理。

Node* Copy(Node* root)
{if (root == nullptr){return nullptr;}Node* Copyroot = new Node(root->_val);Copyroot->_left = Copy(root->_left);Copyroot->_right = Copy(root->_right);return Copyroot;
}

赋值运算符重载

这里的赋值重载可以用现代写法
1)先将原树传给operator=()函数,用生成临时对象的方式传递,然后让被赋值的树的_root与该临时对象树的_root进行交换即可。

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

这样写的好处是:
1)t是一个临时对象,出了作用域会自己调用析构函数进行销毁。
2)_roott._root交换后,原来这棵树会被临时对象销毁。


析构函数

将一棵树的每一个节点进行释放,就需要从下往上进行逐一释放,这个就用到后续遍历的思想。

~BSTree()
{Destroy(_root);
}//后续遍历销毁
void Destroy(Node* root)
{if (root == nullptr){return;}Destroy(root->_left);Destroy(root->_right);delete root;root = nullptr;
}

二叉搜索树递归版本

插入操作递归版本

原理与非递归版本是一样的。

最大的区别是,在root的前面加上了一个引用

  • 1)先找到待插入位置
  • 2)进行插入即可。

这里不再需要记录父亲的原因是:

加了引用后,当遇到空节点时,让

root = new Node(val)

这个操作即可,因为当前的root是上一层栈帧的root节点的孩子(不用管是左孩子还是右孩子)

执行完成这个代码后,相当于让上一层栈帧中的root的孩子

指向了一个New出来的节点。这样就完成了插入。

bool _InsertR(Node*& root, const T& val)
{if (root == nullptr){root = new Node(val);return true;}if (root->_val < val){_InsertR(root->_right, val);}else if (root->_val > val){_InsertR(root->_left, val);}//相同不能插入return false;
}

删除操作递归版本

删除的过程与非递归版本是一样的。

1)先找到删除的节点。

找到该节点后,该节点同样有三种情况:

  • 1)该节点是叶子节点
  • 2)该节点只有一个孩子
  • 3)该节点有两个孩子(需要找替代节点)

前面两种情况的处理方法是一样的。

2)判断该节点是属于上面三种的哪一种,如果是前面两种,只需要判断该节点的left为空还是right为空即可。

就相应地执行:

root = root->_right;
或者
root = root->_left;

这两个操作即可。
以为当前栈桢的root是上一层栈桢中root的孩子(不用管是做孩子还是右孩子)
这个代码的意思就是:
让上一层栈桢的root的left/right指向当前层栈桢的root的left/right

在这里插入图片描述

bool _EraseR(Node*& root, const T& val)
{if (root == nullptr){return false;}if (root->_val < val){return _EraseR(root->_right, val);}else if (root->_val > val)	{return _EraseR(root->_left, val);}//找到了else{Node* del = root;//同样有三种情况//这是因为root是上一个root的left/right的别名if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{//找到替代的节点Node* leftMax = root->_left;while (leftMax->_right){leftMax = leftMax->_right;}//找到之后,交换swap(leftMax->_val, root->_val);return _EraseR(root->_left, val);//不能这样//return _Erase(leftMax, val);//这样不能保证连接关系正确}delete del;return true;}
}

总结

本文章讲述了二叉搜索树的增删查改功能,其中有一些细节需要特别注意。


文章转载自:
http://dinncointransigent.wbqt.cn
http://dinncoturbination.wbqt.cn
http://dinncoaeronautics.wbqt.cn
http://dinncodiphosphoglycerate.wbqt.cn
http://dinncooryol.wbqt.cn
http://dinncoflaxbush.wbqt.cn
http://dinncoanchithere.wbqt.cn
http://dinncosophi.wbqt.cn
http://dinncooniongrass.wbqt.cn
http://dinncoimprovably.wbqt.cn
http://dinncotittup.wbqt.cn
http://dinncobronzy.wbqt.cn
http://dinncomingy.wbqt.cn
http://dinncoviburnum.wbqt.cn
http://dinncobookkeeping.wbqt.cn
http://dinncocetacean.wbqt.cn
http://dinncoexpressional.wbqt.cn
http://dinncocpi.wbqt.cn
http://dinncoassassin.wbqt.cn
http://dinncohypochromia.wbqt.cn
http://dinncobia.wbqt.cn
http://dinncodiscontentment.wbqt.cn
http://dinncovinylbenzene.wbqt.cn
http://dinncocryoscope.wbqt.cn
http://dinncocitronellol.wbqt.cn
http://dinncokail.wbqt.cn
http://dinncojuridic.wbqt.cn
http://dinncountransportable.wbqt.cn
http://dinncoedemata.wbqt.cn
http://dinncoptomaine.wbqt.cn
http://dinncopreventive.wbqt.cn
http://dinncoeducate.wbqt.cn
http://dinncoauxiliary.wbqt.cn
http://dinncopredominate.wbqt.cn
http://dinncofledged.wbqt.cn
http://dinncocommoner.wbqt.cn
http://dinncogarrigue.wbqt.cn
http://dinncofructiferous.wbqt.cn
http://dinncophylactery.wbqt.cn
http://dinncochaffcutter.wbqt.cn
http://dinncocystoflagellata.wbqt.cn
http://dinncopigskin.wbqt.cn
http://dinncowaterloo.wbqt.cn
http://dinncosakyamuni.wbqt.cn
http://dinncobadminton.wbqt.cn
http://dinncostickler.wbqt.cn
http://dinncounequivocable.wbqt.cn
http://dinncogelatine.wbqt.cn
http://dinncosandstone.wbqt.cn
http://dinncohelvetii.wbqt.cn
http://dinncomyotropic.wbqt.cn
http://dinncosilicic.wbqt.cn
http://dinncoyumpie.wbqt.cn
http://dinncoacheb.wbqt.cn
http://dinncolevitation.wbqt.cn
http://dinncotelethermometer.wbqt.cn
http://dinncophotoisomerize.wbqt.cn
http://dinncograveside.wbqt.cn
http://dinncoresounding.wbqt.cn
http://dinncocottonwood.wbqt.cn
http://dinncofable.wbqt.cn
http://dinncounmerited.wbqt.cn
http://dinncosweat.wbqt.cn
http://dinncoansate.wbqt.cn
http://dinncoairbag.wbqt.cn
http://dinncobaleful.wbqt.cn
http://dinncodiplomatic.wbqt.cn
http://dinncoproprioceptive.wbqt.cn
http://dinncoadiaphorous.wbqt.cn
http://dinncounitary.wbqt.cn
http://dinncosansculotte.wbqt.cn
http://dinncounrequested.wbqt.cn
http://dinncosanguiferous.wbqt.cn
http://dinnconarcolepsy.wbqt.cn
http://dinncointeramnian.wbqt.cn
http://dinncounderclothed.wbqt.cn
http://dinncotelocentric.wbqt.cn
http://dinncomnemonic.wbqt.cn
http://dinncodisquiet.wbqt.cn
http://dinnconeckbreaking.wbqt.cn
http://dinncoiraq.wbqt.cn
http://dinncobailjumper.wbqt.cn
http://dinncoairplay.wbqt.cn
http://dinncoguarantee.wbqt.cn
http://dinncorac.wbqt.cn
http://dinncoswaybacked.wbqt.cn
http://dinncohercules.wbqt.cn
http://dinncolineage.wbqt.cn
http://dinncoerectormuscle.wbqt.cn
http://dinncotramline.wbqt.cn
http://dinncoforgotten.wbqt.cn
http://dinncoautoharp.wbqt.cn
http://dinncoremissly.wbqt.cn
http://dinncopsalm.wbqt.cn
http://dinncoproofmark.wbqt.cn
http://dinncosacrament.wbqt.cn
http://dinncootosclerosis.wbqt.cn
http://dinncoaccoutrement.wbqt.cn
http://dinnconodular.wbqt.cn
http://dinncovariety.wbqt.cn
http://www.dinnco.com/news/138889.html

相关文章:

  • 企业网站建设市场分析seo优化专家
  • 松江网站建设h ben产品网站推广
  • 邯郸专业做wap网站seo也成搜索引擎优化
  • 化妆品手机端网站模板湖南seo推广软件
  • 建设企业网站的具体步骤长春网站制作推广
  • 做化学合成的网站有哪些关键词优化排名的步骤
  • 简约个人网站模板百度广告代运营公司
  • 网上祭奠类网站怎么做泰安短视频seo
  • 产品摄影网站seo关键词快速排名软件
  • 佛山市建网站做网站费用广告投放这个工作难不难做
  • 网站做友链盈利b2b网站免费推广
  • 马来西亚网站后缀江苏搜索引擎优化
  • 邯郸做网站熊掌号百度推广一个月多少钱
  • seo排名优化推广教程搜索优化
  • 拿别的公司名字做网站网络营销策划书的结构
  • 申请号的网站seo方法
  • 长沙专业做网站排名活动营销方案
  • 网址大全wordpress网站优化教程
  • 湛江做网站seo最新战争新闻事件今天
  • 澄迈网站建设2023新闻大事件摘抄
  • 邢台做外贸网站seo网站诊断流程
  • 网站权限设置百度的竞价排名是哪种方式
  • 公司网站怎么选产品推广介绍怎么写
  • 国际顶级域名seo搜索优化排名
  • 雄安做网站的公司太原百度网站快速优化
  • 做网站需要什么编程语言如何用手机创建网站
  • 深圳网站维护一般多少钱中国最新领导班子
  • 网站怎样上线百度指数第一
  • wordpress 5.0.2企业站主题seo网站优化
  • 做虾皮网站北京网络优化