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

有什么做宝宝辅食的网站吗优秀营销软文范例500字

有什么做宝宝辅食的网站吗,优秀营销软文范例500字,自己在线制作logo免费模板,北京便宜做网站本期内容我们讲解二叉树的进阶知识,没有看过之前内容的小伙伴建议先看往期内容 二叉树-----补充_KLZUQ的博客-CSDN博客 目录 二叉搜索树 代码实现 基础框架 Insert Find Erase 析构函数 拷贝构造 赋值 二叉搜索树的应用 全部代码 二叉搜索树 二叉搜索树…

本期内容我们讲解二叉树的进阶知识,没有看过之前内容的小伙伴建议先看往期内容

二叉树-----补充_KLZUQ的博客-CSDN博客

目录

二叉搜索树 

代码实现

基础框架

Insert

Find

Erase

析构函数

拷贝构造

赋值

二叉搜索树的应用

全部代码


二叉搜索树 

二叉搜索树又称二叉排序树,它或者是一棵空树 ,或者是具有以下性质的二叉树 :
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树

 由于结构特性,二叉搜索树很适合查找数据,那它最多查找多少次呢?高度次吗?

其实不是的,二叉搜索树是可能会有右边这种情况的,时间复杂度是O(N)

 这其实是不好的,后面我们会讲AVL树和红黑树,他们的时间复杂度是O(longN)

话不多说,下面我们来实现二叉搜索树

代码实现

基础框架

template<class K>
struct BSTreeNode
{BSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;BSTreeNode(const K& key):_left(nullptr), _right(nullptr),_key(key){}
};template<class K>
class BSTree
{typedef BSTreeNode<K> Node;
public:BSTree():_root(nullptr){}bool Insert(const K& key){}
private:Node* _root;
};

我们先写出基本框架,接着我们来实现插入

Insert

假设我们有这样一棵树,我们要插入11,13和16,该怎么办呢?我们将11和root节点对比,11比8大,应该在右边,继续对比11和10,比10大,在右边,11比14小,在左边,比13小,在左边

就成了这个样子,再看13,我们对比后发现树里面已经有13了,所以插入失败,最后看16,16比14大,链接在14的右边即可

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

我们先用循环来实现

下面为了测试,我们写一个中序遍历

void InOrder(){_InOrder(_root);cout << endl;}void _InOrder(Node* root){if (root == NULL){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}

我们写成子函数是因为我们在调用时还得传root,比如封装写成子函数,这样我们就不用传了,下面进行测试

 没有问题,中序遍历出来是有序的

bool InsertR(const K& key){return _InsertR(_root, key);}
private:bool _InsertR(Node*& root, const K& key){if (root == nullptr)//因为引用,所以下面可以直接new{root = new Node(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;}}

我们再看递归版本的,递归版本里参数加了引用,这个引用可以让我们在插入节点时不用找该节点的父亲节点,可谓是神之一手 

Find

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

find也非常简单

bool FindR(const K& key){return _FindR(_root, key);}
private:bool _FindR(Node* root,const K& key)//递归版本{if (root == nullptr){return false;}if (root->_key < key){return _FindR(root->_right, key);}else if (root->_key > key){return _FindR(root->_left, key);}else{return true;}}

还有递归版本的,我们再把子函数写成私有的 

Erase

删除是一个重点,我们有这样一棵树,假设我们要删除7,14和3

7是叶子节点,删除后再把6的右置为空即可,14也还好说,它只有一个孩子,我们可以让10的右节点指向13,最麻烦的是3,我们该如何删除3呢?这里就要用到替换法,用3的左子树的最大节点或者右子树的最小节点来替换,一棵树的最大节点是这棵树的最右边的节点,所以左子树的最大节点很好找,最小的节点就是最左边的,所以右子树的最小节点也很好找

bool Erase(const K& key){Node* parent = nullptr;Node* 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->_right == cur){parent->_right = cur->_right;}else{parent->_left = cur->_right;}}		}//右为空else if (cur->_right == nullptr){if (cur == _root){_root = cur->_left;}else {if (parent->_right == cur){parent->_right = cur->_left;}else{parent->_left = cur->_left;}}			}//左右都不为空else{//找替代节点Node* parent = cur;//这里不能给空,防止leftMax是根节点的左子树的第一个节点Node* leftMax = cur->_left;while (leftMax->_right){parent = leftMax;leftMax = leftMax->_left;}swap(cur->_key, leftMax->_key);if (parent->_left == leftMax){parent->_left = leftMax->_left;}else{parent->_right = leftMax->_left;}cur = leftMax;}delete cur;return true;}}return false;}

删除要考虑的情况非常多,大家一定要画图才能理解

 大家用这几张图画一画,结合代码,里面的坑是非常多的 

下面我们测试一下

没有问题,大家测试时再把整棵树删空测试一下

bool EraseR(const K& key){return _EraseR(_root, key);}
private:bool _EraseR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Node* del = root;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(root->_key, leftMax->_key);return _EraseR(root->_left, key);}delete del;return true;}}

我们再看递归版本,这里同样使用了引用,可以方便很多,大家画图对照一下就可以理解

下面我们再完成一下析构函数

析构函数

~BSTree(){Destroy(_root);}
void Destroy(Node*& root){if (root == nullptr){return;}Destroy(root->_left);Destroy(root->_right);delete root;root = nullptr;}

也是同样使用引用,为了方便置空

拷贝构造

BSTree(const BSTree<K>& t){_root = Copy(t._root);}
Node* Copy(Node* root){if (root == nullptr){return nullptr;}Node* copyroot = new Node(root->_key);copyroot->_left = Copy(root->_left);copyroot->_right = Copy(root->_right);return copyroot;}

拷贝构造这里是不能调用insert的,因为任何顺序的插入都不能保证和原来树的一样,大家可以试一试,而我们这样写拷贝构造就可以解决问题

赋值

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

赋值的话我们直接用现代写法即可

二叉搜索树的应用

1. K 模型: K 模型即只有 key 作为关键码,结构中只需要存储 Key 即可,关键码即为需要搜索到 的值
比如: 给一个单词 word ,判断该单词是否拼写正确 ,具体方式如下:
以词库中所有单词集合中的每个单词作为 key ,构建一棵二叉搜索树
在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。
2. KV 模型:每一个关键码 key ,都有与之对应的值 Value ,即 <Key, Value> 的键值对 。该种方式在现实生活中非常常见:
比如 英汉词典就是英文与中文的对应关系 ,通过英文可以快速找到与其对应的中文,英
文单词与其对应的中文 <word, chinese> 就构成一种键值对;
再比如 统计单词次数 ,统计成功后,给定单词就可快速找到其出现的次数, 单词与其出
现次数就是 <word, count> 就构成一种键值对

 下面我们修改我们上面的程序,把它变成KV的

template<class K, class V >struct BSTreeNode{BSTreeNode<K,V>* _left;BSTreeNode<K,V>* _right;K _key;V _value;BSTreeNode(const K& key, const V& value):_left(nullptr), _right(nullptr), _key(key),_value(value){} };template<class K,class V>class BSTree{typedef BSTreeNode<K,V> Node;public:BSTree():_root(nullptr){}void InOrder(){_InOrder(_root);cout << endl;}Node* FindR(const K& key){return _FindR(_root, key);}bool InsertR(const K& key, const V& value){return _InsertR(_root, key,value);}bool EraseR(const K& key){return _EraseR(_root, key);}private:bool _EraseR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Node* del = root;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(root->_key, leftMax->_key);return _EraseR(root->_left, key);}delete del;return true;}}bool _InsertR(Node*& root, const K& key,const V& value){if (root == nullptr)//因为引用,所以下面可以直接new{root = new Node(key,value);return true;}if (root->_key < key){return _InsertR(root->_right, key,value);}else if (root->_key > key){return _InsertR(root->_left, key,value);}else{return false;}}Node* _FindR(Node* root, const K& key)//递归版本{if (root == nullptr){return nullptr;}if (root->_key < key){return _FindR(root->_right, key);}else if (root->_key > key){return _FindR(root->_left, key);}else{return root;}}void _InOrder(Node* root){if (root == NULL){return;}_InOrder(root->_left);cout << root->_key << ":"<<root->_value<<endl;_InOrder(root->_right);}private:Node* _root;};

这里我删除了一些,下面我们来进行测试

这里我们模拟一个字典 

还有统计水果出现的次数,没有出现的水果我们存进去,出现的让value++

全部代码

namespace key
{template<class K>struct BSTreeNode{BSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;BSTreeNode(const K& key):_left(nullptr), _right(nullptr), _key(key){}};template<class K>class BSTree{typedef BSTreeNode<K> Node;public:BSTree():_root(nullptr){}BSTree(const BSTree<K>& t){_root = Copy(t._root);}BSTree<K>& operator=(BSTree<K> t){swap(_root, t._root);return *this;}~BSTree(){Destroy(_root);}bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);return true;}Node* parent = nullptr;Node* 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 Node(key);if (parent->_key < key){parent->_right = cur;}else{parent->_left = cur;}return true;}bool Find(const K& key){Node* 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){Node* parent = nullptr;Node* 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->_right == cur){parent->_right = cur->_right;}else{parent->_left = cur->_right;}}}//右为空else if (cur->_right == nullptr){if (cur == _root){_root = cur->_left;}else{if (parent->_right == cur){parent->_right = cur->_left;}else{parent->_left = cur->_left;}}}//左右都不为空else{//找替代节点Node* parent = cur;//这里不能给空,防止leftMax是根节点的左子树的第一个节点Node* leftMax = cur->_left;while (leftMax->_right){parent = leftMax;leftMax = leftMax->_left;}swap(cur->_key, leftMax->_key);if (parent->_left == leftMax){parent->_left = leftMax->_left;}else{parent->_right = leftMax->_left;}cur = leftMax;}delete cur;return true;}}return false;}void InOrder(){_InOrder(_root);cout << endl;}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);}private:Node* Copy(Node* root){if (root == nullptr){return nullptr;}Node* copyroot = new Node(root->_key);copyroot->_left = Copy(root->_left);copyroot->_right = Copy(root->_right);return copyroot;}void Destroy(Node*& root){if (root == nullptr){return;}Destroy(root->_left);Destroy(root->_right);delete root;root = nullptr;}bool _EraseR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Node* del = root;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(root->_key, leftMax->_key);return _EraseR(root->_left, key);}delete del;return true;}}bool _InsertR(Node*& root, const K& key){if (root == nullptr)//因为引用,所以下面可以直接new{root = new Node(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 _FindR(Node* root, const K& key)//递归版本{if (root == nullptr){return false;}if (root->_key < key){return _FindR(root->_right, key);}else if (root->_key > key){return _FindR(root->_left, key);}else{return true;}}void _InOrder(Node* root){if (root == NULL){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}private:Node* _root;};void Test(){int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };BSTree<int> t;for (auto e : a){t.InsertR(e);}t.InOrder();t.EraseR(4);t.InOrder();t.EraseR(6);t.InOrder();t.EraseR(7);t.InOrder();t.EraseR(3);t.InOrder();for (auto e : a){t.Erase(e);}t.InOrder();}void Test2(){int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };BSTree<int> t;for (auto e : a){t.Insert(e);}t.InOrder();BSTree<int> t1(t);t1.InOrder();}
}namespace key_value
{template<class K, class V >struct BSTreeNode{BSTreeNode<K,V>* _left;BSTreeNode<K,V>* _right;K _key;V _value;BSTreeNode(const K& key, const V& value):_left(nullptr), _right(nullptr), _key(key),_value(value){} };template<class K,class V>class BSTree{typedef BSTreeNode<K,V> Node;public:BSTree():_root(nullptr){}void InOrder(){_InOrder(_root);cout << endl;}Node* FindR(const K& key){return _FindR(_root, key);}bool InsertR(const K& key, const V& value){return _InsertR(_root, key,value);}bool EraseR(const K& key){return _EraseR(_root, key);}private:bool _EraseR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Node* del = root;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(root->_key, leftMax->_key);return _EraseR(root->_left, key);}delete del;return true;}}bool _InsertR(Node*& root, const K& key,const V& value){if (root == nullptr)//因为引用,所以下面可以直接new{root = new Node(key,value);return true;}if (root->_key < key){return _InsertR(root->_right, key,value);}else if (root->_key > key){return _InsertR(root->_left, key,value);}else{return false;}}Node* _FindR(Node* root, const K& key)//递归版本{if (root == nullptr){return nullptr;}if (root->_key < key){return _FindR(root->_right, key);}else if (root->_key > key){return _FindR(root->_left, key);}else{return root;}}void _InOrder(Node* root){if (root == NULL){return;}_InOrder(root->_left);cout << root->_key << ":"<<root->_value<<endl;_InOrder(root->_right);}private:Node* _root;};void test(){BSTree<string, string> dict;dict.InsertR("insert", "插入");dict.InsertR("right", "右边");dict.InsertR("sort", "排序");dict.InsertR("left", "左边");dict.InsertR("date", "日期");string str;while (cin >> str){BSTreeNode<string, string>* ret = dict.FindR(str);if (ret){cout << ret->_value << endl;}else{cout << "无此单词" << endl;}}}void test2(){string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜",
"苹果", "香蕉", "苹果", "香蕉" };BSTree<string, int> countTree;for (auto& str : arr){auto ret = countTree.FindR(str);if (ret == nullptr){countTree.InsertR(str, 1);}else{ret->_value++;}}countTree.InOrder();}
}

以上即为本期全部内容,希望大家可以有所收获

如有错误,还请指正


文章转载自:
http://undiscerned.zfyr.cn
http://sistern.zfyr.cn
http://margin.zfyr.cn
http://permian.zfyr.cn
http://drillion.zfyr.cn
http://systematizer.zfyr.cn
http://angiocardioraphy.zfyr.cn
http://inlace.zfyr.cn
http://trefa.zfyr.cn
http://waldensian.zfyr.cn
http://unornamented.zfyr.cn
http://novosibirsk.zfyr.cn
http://acmeist.zfyr.cn
http://metalaw.zfyr.cn
http://surroyal.zfyr.cn
http://accessories.zfyr.cn
http://teagirl.zfyr.cn
http://maebashi.zfyr.cn
http://afraid.zfyr.cn
http://chrysomelid.zfyr.cn
http://prefectorial.zfyr.cn
http://lagan.zfyr.cn
http://roundeye.zfyr.cn
http://aramaic.zfyr.cn
http://crocky.zfyr.cn
http://vapor.zfyr.cn
http://cursing.zfyr.cn
http://rainily.zfyr.cn
http://isomery.zfyr.cn
http://venery.zfyr.cn
http://grammar.zfyr.cn
http://cottian.zfyr.cn
http://sturmer.zfyr.cn
http://somatopsychic.zfyr.cn
http://niphablepsia.zfyr.cn
http://armageddon.zfyr.cn
http://fusionist.zfyr.cn
http://allemande.zfyr.cn
http://kelpy.zfyr.cn
http://unformat.zfyr.cn
http://criticism.zfyr.cn
http://winebibbing.zfyr.cn
http://sinusitis.zfyr.cn
http://corresponsively.zfyr.cn
http://nielsbohrium.zfyr.cn
http://dihydroxyphenylalanine.zfyr.cn
http://chaudfroid.zfyr.cn
http://strychnine.zfyr.cn
http://dixy.zfyr.cn
http://innominate.zfyr.cn
http://reapportionment.zfyr.cn
http://foeman.zfyr.cn
http://boulevard.zfyr.cn
http://naida.zfyr.cn
http://intermissive.zfyr.cn
http://jervis.zfyr.cn
http://comminute.zfyr.cn
http://banco.zfyr.cn
http://kikoi.zfyr.cn
http://pothunter.zfyr.cn
http://dyeability.zfyr.cn
http://byroad.zfyr.cn
http://lambwool.zfyr.cn
http://penumbra.zfyr.cn
http://tirelessly.zfyr.cn
http://dendrometer.zfyr.cn
http://subsensible.zfyr.cn
http://rapine.zfyr.cn
http://electropathy.zfyr.cn
http://neuroepithelium.zfyr.cn
http://khalif.zfyr.cn
http://unfordable.zfyr.cn
http://bloodstock.zfyr.cn
http://reachable.zfyr.cn
http://shankbone.zfyr.cn
http://reinvent.zfyr.cn
http://exfoliation.zfyr.cn
http://amazement.zfyr.cn
http://curvifoliate.zfyr.cn
http://vowelless.zfyr.cn
http://laryngectomee.zfyr.cn
http://monkeyshine.zfyr.cn
http://accommodate.zfyr.cn
http://exp.zfyr.cn
http://sawblade.zfyr.cn
http://karroo.zfyr.cn
http://tough.zfyr.cn
http://ergotoxine.zfyr.cn
http://laeotropic.zfyr.cn
http://tying.zfyr.cn
http://hydratable.zfyr.cn
http://pleasing.zfyr.cn
http://athleticism.zfyr.cn
http://complexional.zfyr.cn
http://nudzh.zfyr.cn
http://phencyclidine.zfyr.cn
http://menshevist.zfyr.cn
http://chronologize.zfyr.cn
http://cinerama.zfyr.cn
http://gallonage.zfyr.cn
http://www.dt0577.cn/news/110659.html

相关文章:

  • wordpress带格式的字体怎么修改搜索引擎优化是什么
  • 网站什么时候做解析下载百度极速版
  • 华为建站模板sem是什么意思
  • 如何上传程序到网站空间百度引擎搜索入口
  • 开发公司账务处理温州seo排名优化
  • 网站建设与管理asp线上网络平台推广
  • 网站建设布局企业网站制作教程
  • 建设网站带后台管理申请一个网站
  • 网页设计css网站推广和精准seo
  • 平江外贸网站推广找哪家如何使用网络营销策略
  • 建设网站主机可以用吗怎么建免费网站
  • 开发次元世界笔趣阁站长工具seo综合查询分析
  • 淮安网站建设公司网络推广靠谱吗
  • 井陉县城乡建设局网站搜索率最高的关键词
  • wordpress对接公众号长沙官网网站推广优化
  • 公司内部网站规划关键词搜索网站
  • 大连海外网站建设长尾关键词快速排名软件
  • 服装企业网站模板百度指数怎么查询
  • wordpress 外部链接插件宁波谷歌优化
  • 网站建设套模板国内新闻最新消息简短
  • 做网站 带宽 多少营销管理培训课程培训班
  • 开发者模式打开有什么影响石家庄seo全网营销
  • 昆明专业做网站多少钱上海网站建设开发
  • 网站建设的要求及标准怎么让网站快速收录
  • 做网站责任月饼营销软文
  • 做导购网站有哪些黑帽seo什么意思
  • 重庆造价信息网官网首页上海比较好的seo公司
  • 精仿小米社区wordpress模板站长工具seo优化建议
  • 餐饮加盟什么网站建设推广引流方法有哪些推广方法
  • 建设局是干什么的宁波seo网络推广优质团队