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

图书网站建设实训心得企业网站快速排名

图书网站建设实训心得,企业网站快速排名,舆情报告分析10000字,手机网站 扁平化趋势文章目录 二叉搜索树二叉搜索树的基本实现原理 二叉搜索树的实现非递归版本的实现递归版本的实现 二叉搜索树 二叉搜索树也叫做二叉排序树,可以是空树,也可以是满足一些要求的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点…

文章目录

  • 二叉搜索树
    • 二叉搜索树的基本实现原理
  • 二叉搜索树的实现
    • 非递归版本的实现
    • 递归版本的实现

二叉搜索树

二叉搜索树也叫做二叉排序树,可以是空树,也可以是满足一些要求的二叉树

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

对于一种数据结构来说,大概率是实现增删查改这四个基本功能,这里实现的是增删查,对于改不实现的原因后续解释:

二叉搜索树的基本实现原理

1. 二叉搜索树的查找
a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找
b、最多查找高度次,走到到空,还没找到,这个值不存在

2. 二叉搜索树的插入
插入的具体过程如下:
a. 树为空,则直接新增节点,赋值给root指针
b. 树不空,按二叉搜索树性质查找插入位置,插入新节点

3. 二叉搜索树的删除
首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情况:
a. 要删除的结点无孩子结点
b. 要删除的结点只有左孩子结点
c. 要删除的结点只有右孩子结点
d. 要删除的结点有左、右孩子结点

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

二叉搜索树的实现

二叉树中节点是最基本的信息,因此先进行节点的定义

template <class K>
struct Node
{Node(int key = 0):_left(nullptr), _right(nullptr), _key(key){}Node* _left;Node* _right;K _key;
};

非递归版本的实现

1. 插入

对于二叉搜索树来说,插入的逻辑是很简单的,如果插入的元素比目前的节点要大,就插入到右边,如果比目前的节点小,就插入到左边:

	bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);}else{Node* cur = _root;Node* parent = cur;while (cur){parent = cur;if (key > cur->_key){cur = cur->_right;}else if (key < cur->_key){cur = cur->_left;}else{return false;}}if (parent->_key > key){parent->_left = new Node(key);}else{parent->_right = new Node(key);}}return true;}

2. 删除

二叉搜索树的删除较为复杂,下面分几种情况来进行讨论:

  1. 左根或右根为空

在这里插入图片描述
由于这种情况下最多只有一边有值,因此直接删除这个节点即可,令这个节点的父亲节点指向它的下一个节点

  1. 如果两边都有分支

解决的方法是,从要删除的这个节点的右子树中寻找一个可以替换它位置的数,这个数在寻找的时候选取的是右子树中的最小值,也就是右子树中的最左边的值就是所需要的值,交换后依旧可以满足二叉搜索树的条件,因此可以这样选择

	bool Erase(const K& key){Node* cur = _root;Node* parent = cur;while (cur){if (key > cur->_key){parent = cur;cur = cur->_right;}else if (key < cur->_key){parent = cur;cur = cur->_left;}else{if (cur->_left == nullptr){// 左为空if (cur == _root){_root = cur->_right;}else{if (key < parent->_key){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}}else if (cur->_right == nullptr){// 右为空if (cur == _root){_root = cur->_left;}else{if (key < parent->_key){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}}else{// 左右都不为空parent = cur;Node* subleft = cur->_right;while (subleft->_left){parent = subleft;subleft = subleft->_left;}swap(cur->_key, subleft->_key);if (subleft == parent->_left){parent->_left = subleft->_right;}else{parent->_right = subleft->_right;}}return true;}}return false;}

3. 查找

有了前面的基础,查找的原理就很简单了,如果要找的值比当前值小,就到左树中寻找,如果要找的值比当前值大,就到右树中寻找,直到最后找到这个值为止,否则返回找不到

	bool Find(const K& key){Node* cur = _root;while (cur){if (key > cur->_key){cur = cur->_right;}else if (key < cur->_key){cur = cur->_left;}else{return true;}}return false;}

递归版本的实现

	bool InsertR(const K& key){return _Insert(_root, key);}bool EraseR(const K& key){return _Erase(_root, key);}bool FindR(const K& key){return _Find(_root, key);}void InOrder(){_InOrder(_root);cout << endl;}
private:bool _Insert(Node*& root, const K& key){if (root == nullptr){root = new Node(key);return true;}if (key > root->_key){_Insert(root->_right, key);}else if(key<root->_key){_Insert(root->_left, key);}return false;}bool _Erase(Node*& root, const K& key){if (root==nullptr){return false;}if (key < root->_key){_Erase(root->_left, key);}else if (key > root->_key){_Erase(root->_right, key);}else{if (root->_left == nullptr){Node* del = root;root = root->_right;delete del;return true;}else if (root->_right == nullptr){Node* del = root;root = root->_left;delete del;return true;}else{Node* subleft = root->_right;while (subleft->_left){subleft = subleft->_left;}swap(root->_key, subleft->_key);return _Erase(root->_right, key);}}}bool _Find(Node* root, const K& key){if (root == nullptr){return false;}if (key < root->_key){return _Find(root->_left, key);}else if (key > root->_key){return _Find(root->_right, key);}else{return true;}}void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}

验证代码是否成功:

int main()
{int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };BSTree<int> bst;cout << "非递归版本:" << endl;for (auto e : a){bst.Insert(e);}bst.InOrder();for (auto e : a){bst.Erase(e);bst.InOrder();}cout << "递归版本:" << endl;for (auto e : a){bst.InsertR(e);}bst.InOrder();for (auto e : a){bst.EraseR(e);bst.InOrder();}return 0;
}

实验结果:

在这里插入图片描述
由此可知,这里的二叉搜索树的实现是没有问题的

完整代码:

#include <iostream>
using namespace std;template <class K>
struct Node
{Node(int key = 0):_left(nullptr), _right(nullptr), _key(key){}Node* _left;Node* _right;K _key;
};template <class K>
class BSTree
{typedef Node<K> Node;
public:bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);}else{Node* cur = _root;Node* parent = cur;while (cur){parent = cur;if (key > cur->_key){cur = cur->_right;}else if (key < cur->_key){cur = cur->_left;}else{return false;}}if (parent->_key > key){parent->_left = new Node(key);}else{parent->_right = new Node(key);}}return true;}bool Erase(const K& key){Node* cur = _root;Node* parent = cur;while (cur){if (key > cur->_key){parent = cur;cur = cur->_right;}else if (key < cur->_key){parent = cur;cur = cur->_left;}else{if (cur->_left == nullptr){// 左为空if (cur == _root){_root = cur->_right;}else{if (key < parent->_key){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}}else if (cur->_right == nullptr){// 右为空if (cur == _root){_root = cur->_left;}else{if (key < parent->_key){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}}else{// 左右都不为空parent = cur;Node* subleft = cur->_right;while (subleft->_left){parent = subleft;subleft = subleft->_left;}swap(cur->_key, subleft->_key);if (subleft == parent->_left){parent->_left = subleft->_right;}else{parent->_right = subleft->_right;}}return true;}}return false;}bool Find(const K& key){Node* cur = _root;while (cur){if (key > cur->_key){cur = cur->_right;}else if (key < cur->_key){cur = cur->_left;}else{return true;}}return false;}bool InsertR(const K& key){return _Insert(_root, key);}bool EraseR(const K& key){return _Erase(_root, key);}bool FindR(const K& key){return _Find(_root, key);}void InOrder(){_InOrder(_root);cout << endl;}
private:bool _Insert(Node*& root, const K& key){if (root == nullptr){root = new Node(key);return true;}if (key > root->_key){_Insert(root->_right, key);}else if(key<root->_key){_Insert(root->_left, key);}return false;}bool _Erase(Node*& root, const K& key){if (root==nullptr){return false;}if (key < root->_key){_Erase(root->_left, key);}else if (key > root->_key){_Erase(root->_right, key);}else{if (root->_left == nullptr){Node* del = root;root = root->_right;delete del;return true;}else if (root->_right == nullptr){Node* del = root;root = root->_left;delete del;return true;}else{Node* subleft = root->_right;while (subleft->_left){subleft = subleft->_left;}swap(root->_key, subleft->_key);return _Erase(root->_right, key);}}}bool _Find(Node* root, const K& key){if (root == nullptr){return false;}if (key < root->_key){return _Find(root->_left, key);}else if (key > root->_key){return _Find(root->_right, key);}else{return true;}}void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}Node* _root = nullptr;
};
http://www.qdjiajiao.com/news/11193.html

相关文章:

  • 用dw可以做网站吗google搜索引擎免费入口
  • wordpress修改文章链接seo关键词优化排名
  • 辽阳建设网站找哪家品牌推广内容
  • 做网站目录搜索引擎关键词优化方案
  • 海沧建设网站多少最有吸引力的营销模式
  • 金华农村网站建设最近三天的国际新闻大事
  • 做计算机题的网站百度seo报价方法
  • 网站建设工作进度表广州优化seo
  • 中国电影家协会官网谷歌关键词排名优化
  • 网站如何做排名百度外推排名代做
  • 投稿的网站seo推广教程seo高级教程
  • WordPress新版文章标签seo系统教程
  • 长春火车站到吉大二院想学销售去哪培训
  • 要给公司做一个网站怎么做成都网站优化
  • 金华做网站的公司网络营销推广的方法有哪些
  • 嘉兴网站建设咨询杭州优化商务服务公司
  • 中国建设银行官网站e路护下载seo优化推广业务员招聘
  • 无锡知名网站进入百度一下官网
  • 代码删除wordpress分类目录名游戏优化大师
  • 学习怎么做网站大连百度推广公司
  • 北京丰台做网站在线生成个人网站源码
  • 8网站建设做网站关键词排名查询api
  • 制作网站用什么软件好北京首页关键词优化
  • 设计前沿的网站推广优化网站排名教程
  • 3d建模要学多久谷歌seo搜索引擎下载
  • 珠宝首饰网站建设策划书汕头seo网站建设
  • 就有公司域名怎么建设网站如何做个人网站
  • 求生之路2怎么做非官方网站获客软件
  • 佛山做网站业务工资自媒体视频剪辑培训班
  • 程序做网站好还是app好上海seo网站优化软件