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

网站seo优化方案项目策划书个人简历表下载可填写

网站seo优化方案项目策划书,个人简历表下载可填写,专门做外贸的网站,新网官网封装红黑树实现mymap和myset 1. 源码及框架分析2. 模拟实现map和set2.1 实现出复⽤红⿊树的框架,并⽀持insert2.2 ⽀持iterator的实现2.3 map⽀持[]2.4 完整实现 1. 源码及框架分析 SGI-STL30版本源代码,map和set的源代码在map/set/stl_map.h/stl_set.h…

封装红黑树实现mymap和myset

  • 1. 源码及框架分析
  • 2. 模拟实现map和set
    • 2.1 实现出复⽤红⿊树的框架,并⽀持insert
    • 2.2 ⽀持iterator的实现
    • 2.3 map⽀持[]
    • 2.4 完整实现

1. 源码及框架分析

SGI-STL30版本源代码,map和set的源代码在map/set/stl_map.h/stl_set.h/stl_tree.h等⼏个头⽂件
中。
map和set的实现结构框架核⼼部分截取出来如下:

// set
#ifndef __SGI_STL_INTERNAL_TREE_H
#include <stl_tree.h>
#endif
#include <stl_set.h>
#include <stl_multiset.h>
// map
#ifndef __SGI_STL_INTERNAL_TREE_H
#include <stl_tree.h>
#endif
#include <stl_map.h>
#include <stl_multimap.h>
// stl_set.h
template <class Key, class Compare = less<Key>, class Alloc = alloc>
class set {
public:// typedefs:typedef Key key_type;typedef Key value_type;
private:typedef rb_tree<key_type, value_type, identity<value_type>, key_compare, Alloc> rep_type;rep_type t; // red-black tree representing set
};
// stl_map.h
template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
class map {
public:
// typedefs:typedef Key key_type;typedef T mapped_type;typedef pair<const Key, T> value_type;
private:typedef rb_tree<key_type, value_type, select1st<value_type>, key_compare, Alloc> rep_type;rep_type t; // red-black tree representing map
};
// stl_tree.h
struct __rb_tree_node_base
{typedef __rb_tree_color_type color_type;typedef __rb_tree_node_base* base_ptr;color_type color; base_ptr parent;base_ptr left;base_ptr right;
};
// stl_tree.h
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc 
= alloc>
class rb_tree {
protected:typedef void* void_pointer;typedef __rb_tree_node_base* base_ptr;typedef __rb_tree_node<Value> rb_tree_node;typedef rb_tree_node* link_type;typedef Key key_type;typedef Value value_type;
public:// insert⽤的是第⼆个模板参数左形参 pair<iterator,bool> insert_unique(const value_type& x);// erase和find⽤第⼀个模板参数做形参 size_type erase(const key_type& x);iterator find(const key_type& x);
protected:size_type node_count; // keeps track of size of treelink_type header;
};
template <class Value>
struct __rb_tree_node : public __rb_tree_node_base
{typedef __rb_tree_node<Value>* link_type;Value value_field;};

SGI版本中插入的结点中数据类型是value_type,通过key_type进行查找。

• set实例化rb_tree时第⼆个模板参数给的是key,map实例化rb_tree时第⼆个模板参数给的是pair<const key,T>,这样⼀颗红⿊树既可以实现set也可以实现map

• rb_tree第⼆个模板参数Value已经控制了红⿊树结点中存储的数据类型,为什么还要传第⼀个模板参数Key呢?尤其是set,两个模板参数是⼀样的,但是是为了代码能复用。这样在针对map的情况下就不需要重新定义模版了

2. 模拟实现map和set

2.1 实现出复⽤红⿊树的框架,并⽀持insert

• 参考源码框架,map和set复⽤之前我们实现的红⿊树。
• 我们这⾥相⽐源码调整⼀下,key参数就⽤K,value参数就⽤V,红⿊树中的数据类型,我们使⽤T。
• 其次因为RBTree实现了泛型不知道T参数导致是K,还是pair<K,V>,那么insert内部进⾏插⼊的是T逻辑⽐较的是K,而set中T和K是一个东西,map中T和K不是同一个东西所以我们在map和set层分别实现⼀个MapKeyOfT和SetKeyOfT的仿函数传给RBTree的KeyOfT,然后RBTree中通过KeyOfT仿函数取出T类型对象中的key,再进⾏⽐较,具体细节参考如下代码实现。

class map
{struct MapKeyOfT{const K& operator()(const pair<K, V>& kv){return kv.first;}};public:typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::Iterator iterator;typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::ConstIterator const_iterator;
template<class K>
class set
{struct SetKeyOfT{const K& operator()(const K& key){return key;}};public:typedef typename RBTree<K, const K, SetKeyOfT>::Iterator iterator;typedef typename RBTree<K, const K, SetKeyOfT>::ConstIterator const_iterator;
template<class K, class T, class KeyOfT>
class RBTree
{
private:typedef RBTreeNode<T> Node;Node* _root = nullptr;public:bool Insert(const T& data){if (_root == nullptr){_root = new Node(data);_root->_col = BLACK;return true;}KeyOfT kot;Node* parent = nullptr;Node* cur = _root;while (cur){if (kot(cur->_data) < kot(data)){parent = cur;cur = cur->_right;}else if (kot(cur->_data) > kot(data)){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(data);Node* newnode = cur;// 新增结点。颜⾊给红⾊ cur->_col = RED;if (kot(parent->_data) < kot(data)){parent->_right = cur;}else{parent->_left = cur;}cur->_parent = parent;//...return true;}
}

2.2 ⽀持iterator的实现

iterator实现思路分析
• iterator实现的⼤框架跟list的iterator思路是⼀致的,⽤⼀个类型封装结点的指针,再通过重载运算符实现,迭代器像指针⼀样访问的⾏为。
• 这⾥的难点是operator++和operator–的实现。map和set的迭代器⾛的是中序遍历,左⼦树->根结点->右⼦树,那么begin()会返回中序第⼀个结点的iterator也就是最左的结点
• 迭代器++的核⼼逻辑就是不看全局,只看局部,只考虑当前中序局部要访问的下⼀个结点。
• 迭代器++时,如果it指向的结点的右⼦树不为空,代表当前结点已经访问完了(指左结点当前结点),++要访问下⼀个结点是当前结点的右⼦树的最左结点即可。
• 迭代器++时,如果it指向的结点的右⼦树空,代表当前结点已经访问完了且当前结点所在的⼦树也访问完了(要返回了),要访问的下⼀个结点在当前结点的祖先⾥⾯,所以要沿着当前结点到根的祖先路径向上找。
• 如果当前结点是⽗亲的左,根据中序左⼦树->根结点->右⼦树,那么下⼀个访问的结点就是当前结点的⽗亲;
• 如果当前结点是⽗亲的右,根据中序左⼦树->根结点->右⼦树,当前当前结点所在的⼦树访问完了,当前结点所在⽗亲的⼦树也访问完了,那么下⼀个访问的需要继续往根的祖先中去找,直到找到孩⼦是⽗亲左的那个祖先就是中序要问题的下⼀个结点。
• end()如何表⽰呢?到根时没有⽗亲,没有找到孩⼦是⽗亲左的那个祖先,这是⽗亲为空了,那我们就把it中的结点指针置为nullptr,我们⽤nullptr去充当end。

如何这样的话无法实现end()–
stl源码中红⿊树增加了⼀个哨兵位头结点做为end(),这哨兵位头结点和根互为⽗亲,左指向最左结点,右指向最右结点。
• 迭代器–的实现跟++的思路完全类似,逻辑正好反过来即可,因为他访问顺序是右⼦树->根结点->左⼦树,具体参考下⾯代码实现。
• set的iterator也不⽀持修改,我们把set的第⼆个模板参数改成const K即可, RBTree<K, const K, SetKeyOfT> _t;
• map的iterator不⽀持修改key但是可以修改value,我们把map的第⼆个模板参数pair的第⼀个参数改成const K即可, RBTree<K, pair<const K, V>, MapKeyOfT> _t;

template<class T, class Ref, class Ptr>
struct RBTreeIterator
{typedef RBTreeNode<T> Node;typedef RBTreeIterator<T, Ref, Ptr> Self;Node* _node;Node* _root;RBTreeIterator(Node* node, Node* root):_node(node), _root(root)//为了支持end()--的操作,否则逻辑实现起来比较复杂{}Self operator++(){if (_node->_right){// 右不为空,中序下一个访问的节点是右子树的最左(最小)节点Node* min = _node->_right;while (min->_left){min = min->_left;}_node = min;}else{// 右为空,祖先里面孩子是父亲左的那个祖先Node* cur = _node;Node* parent = cur->_parent;while (parent && cur == parent->_right){cur = parent;parent = cur->_parent;}_node = parent;}return *this;}Self operator--(){if (_node == nullptr)  // --end(){// --end()我们要去找到中序遍历的最后一个结点,找这个结点得从根开始遍历但是迭代器没有封装根我们如何去找呢?因此这里要封装根Node* rightMost = _root;while (rightMost && rightMost->_right){rightMost = rightMost->_right;}_node = rightMost;}else if (_node->_left){// 左子树不为空,中序左子树最后一个Node* rightMost = _node->_left;while (rightMost->_right){rightMost = rightMost->_right;}_node = rightMost;}else{// 孩子是父亲右的那个祖先Node* cur = _node;Node* parent = cur->_parent;while (parent && cur == parent->_left){cur = parent;parent = cur->_parent;}_node = parent;}return *this;}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator!= (const Self& s) const{return _node != s._node;}bool operator== (const Self& s) const{return _node == s._node;}
};

2.3 map⽀持[]

• map要⽀持[]主要需要修改insert返回值⽀持,修改RBtree中的insert返回值为
pair<Iterator, bool> Insert(const T& data)• 有了insert⽀持[]实现就很简单了,具体参考下⾯代码实现

pair<iterator, bool> insert(const pair<K, V>& kv){return _t.Insert(kv);}V& operator[](const K& key){pair<iterator, bool> ret = insert(make_pair(key, V()));return ret.first->second;}

2.4 完整实现

template<class K, class V>
class map
{struct MapKeyOfT{const K& operator()(const pair<K, V>& kv){return kv.first;}};public:typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::Iterator iterator;typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::ConstIterator const_iterator;iterator begin(){return _t.Begin();}iterator end(){return _t.End();}const_iterator begin() const{return _t.Begin();}const_iterator end()  const{return _t.End();}pair<iterator, bool> insert(const pair<K, V>& kv){return _t.Insert(kv);}V& operator[](const K& key){pair<iterator, bool> ret = insert({ key, V() });return ret.first->second;}private:RBTree<K, pair<const K, V>, MapKeyOfT> _t;
};

文章转载自:

http://KGGqgNLt.mmkrd.cn
http://T6MFdnbZ.mmkrd.cn
http://yO7HVXtr.mmkrd.cn
http://QOorY7BD.mmkrd.cn
http://VK69Hkb3.mmkrd.cn
http://ZUYeXPfr.mmkrd.cn
http://JBZEXYn1.mmkrd.cn
http://k3FoUTaS.mmkrd.cn
http://mxAtF7jA.mmkrd.cn
http://jBpesB4z.mmkrd.cn
http://nZIFMlKn.mmkrd.cn
http://fwp4zPVk.mmkrd.cn
http://l4VXntv8.mmkrd.cn
http://lRh2tBtY.mmkrd.cn
http://spL6EH2w.mmkrd.cn
http://L8X28eij.mmkrd.cn
http://jV3Z5CEe.mmkrd.cn
http://AZzdyjzO.mmkrd.cn
http://LYNuyH1I.mmkrd.cn
http://p8FH4B09.mmkrd.cn
http://gm1ksih3.mmkrd.cn
http://BfbzqIVJ.mmkrd.cn
http://MzqAnAgH.mmkrd.cn
http://DqRxg17Y.mmkrd.cn
http://0ntR5l7A.mmkrd.cn
http://UTFIQDZV.mmkrd.cn
http://HiWyKl7b.mmkrd.cn
http://BYKAS5tx.mmkrd.cn
http://gWWBu2dt.mmkrd.cn
http://dj4j1wtL.mmkrd.cn
http://www.dtcms.com/wzjs/734401.html

相关文章:

  • 网站优化内链怎么做做网站建设要学多久
  • python 网站开发 实例手机seo关键词优化
  • 杭州网站制作平台公司旅行社网站模板
  • asp access网站架设教程建设网站的用途
  • 网站首页图片素材长图郴州买房网站
  • 4399游戏盒下载官方网站无锡百度网站推广
  • ps如何做音乐网站怎么做网站平台
  • 网站域名去哪买网站安全架构
  • 郑州网站建设网络公司网门app下载
  • 网站建设开票税收分类买卖网站
  • 手绘风格的网站济南比较大的网站制作公司
  • 免费的网站制作平台青岛网站推广的价格
  • 影视 wordpress苏州seo公司 翼好
  • 书店建设网站的能力网站带后台免费下载
  • 国内网站开发不用wordpress足球直播网站开发定制
  • 会展行业门户网站建设个人简历网免费模板
  • 网站运行团队建设wordpress search制作
  • 用dw建设网站娱乐公司网站建站背景介绍
  • 公司有必要建设网站吗科普重庆网站
  • 网站百度关键词排名软件查询网ip138子域名
  • 前端做的网站网站建设栏目结构表
  • iis添加网站的物理路径2016企业网站建设合同
  • 怎么在电脑上做网站注册公司都需要什么材料
  • 公司招聘一个网站建设来做推广如何办好公司网站
  • 南平摩托车罚款建设网站缴费谷歌浏览器安卓版下载
  • 互联网做网站建设网站都要学些什么问题
  • 怎样做商城网站的推广企业网站建设报价明细表
  • 服装厂家东莞网站建设网站如何做问卷调查报告
  • 建设网站成本动漫设计专业就业方向
  • 苏州网站建设哪家更好成都高端网页开发公司