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

西安市建设工程交易中心网站网站及搜索引擎优化建议

西安市建设工程交易中心网站,网站及搜索引擎优化建议,营业执照注册网站,网页设计与制作第四版目录 一,实现list所需要包含的三个类 二,三个类的实现 1.list_node 2.list类 3.iterator_list类 三,功能实现 1.list类里的push_back() 2.iterator类里的运算符重载 3,list类里面的功能函数 1.insert(&#xff…

 

目录

一,实现list所需要包含的三个类

二,三个类的实现

1.list_node

2.list类

 3.iterator_list类

三,功能实现

1.list类里的push_back()

  2.iterator类里的运算符重载

3,list类里面的功能函数

1.insert()

2.erase()函数

3.clear()与析构函数

4.拷贝构造函数赋值运算符重载

5.打印函数


一,实现list所需要包含的三个类

     因为list是一个带头双向循环链表。所以list的实现会比较的复杂一些。总得来说,实现一个双向带头循环链表需要构造三个类。1.list类,2.list_node类,3.list_iterator类。前两个类相信大家会比较的熟悉。第三个类大家会比较不熟悉,因为它是一个迭代器的类。也就是说这个类是迭代器的封装。它的实现很有价值,因为它能让我们在使用list时也可以像之前的数据结构一样方便。

二,三个类的实现

1.list_node

 这首先要实现的便是节点类。这个类是最容易实现的。这个类的作用便是给要产生的节点画一个图,定义一下这个节点的结构和类型。代码如下:

template<class T>//模板struct list_node{list_node(const T& val =T()//匿名对象 )//构造函数起初始化的作用:val(val), prev(nullptr), next(nullptr){}T val;list_node<T>* prev;list_node<T>* next;};

现在你看到了,这个节点的结构便是这样。其实这与之前实现的那个带头双向循环链表的结构差不多。不过,在cpp中引入了模板的概念,所以这个节点便可以调用模板参数来进行泛化。

2.list类

list类的定义可太简单了。list的成员变量只有一个参数,便是_head。这是哨兵位的头节点。当然还有一个无参的构造函数和一个功能函数。代码如下:

template<class T>class list{ public:typedef list_node<T> Node;void empty()//初始化功能函数。{_head = new Node;_head->prev = _head;_head->next = _head;}list()//构造函数{empty();}private:Node* _head;};

当然,这里的list类也是要用模板来进行泛化的。

 3.iterator_list类

这个类就算是比较复杂的一个类了。因为迭代器要实现两种重载版本:1.普通版本。2.const版本。所以迭代器类的模板参数会有三个:

template <class T, class Ref, class ptr>

这三个模板参数会重载两种版本的三个参数:T对象,T&,T指针类型。在这个类里面也只有一个成员:_node。类型与list类里面的成员类型相同。该类代码如下:

template <class T, class Ref, class ptr>struct iterator_list{typedef list_node<T> Node;iterator_list(Node* node):_node(node){}Node* _node;};

三,功能实现

1.list类里的push_back()

首先来实现一个push_back()函数,这个函数的作用便是实现尾插数据。逻辑十分简单,代码如下:

void push_back(const T& val){Node* newnode = new Node(val);Node* tail = _head->prev;tail->next = newnode;newnode->prev = tail;newnode->next = _head;_head->prev = newnode;}

写完这个以后,我便想要通过显示list里的数据来验证答案,但是很显然,我们做不到。因为list是一个自定义的类。但是我们有办法,所以我们便可以通过iterator来达到这个目的。所以我们必须在iterator类里面实现几个运算符重载。

  2.iterator类里的运算符重载

首先先实先这三个运算符重载:1.*,2.++,3.!=

代码如下:

        Ref operator *()//Ref代表T&{return _node->val;}self operator++(){_node = _node->next;return *this;}bool operator!=(self& it){return _node != it._node;}

然后再在list类里面实现begin()与end()函数之后便可以实现范围for的使用了,end与begin代码如下:

       //实现两个版本的begin与enditerator begin(){return _head->next;}iterator end(){return _head;}const_iterator begin()const{return _head->next;}const_iterator end()const{return _head;}

在实现了上面的代码以后,为了让迭代器的功能更加全面,那我们再实现几个函数重载。再iterator_list里面的全部运算符重载如下:

       Ref operator *(){return _node->val;}self& operator++()//前置++{_node = _node->next;return *this;}self operator++(int)//后置++{Node* tmp(*this);_node = _node->next;return tmp;}self& operator --()//前置--{_node = _node->prev;return *this;}self operator--(int)//后置--{Node* tmp(*this);_node = _node->prev;return tmp;}bool operator!=(const self& it)//若用引用便要加上const{return _node != it._node;}bool operator==(self& it){return _node == it._node;}self& operator+(int n){while (n){_node = _node->next;n--;}return *this;}ptr operator->()//箭头解引用{return &_node->val;}

在实现了这些运算符重载以后,list类里面的功能函数便好写了许多。

3,list类里面的功能函数

1.insert()

这个函数实现的功能便是在pos位置之前插入一个新的节点。这个pos的类型是迭代器类型。在list类里边的迭代器重定义为:

typedef iterator_list<T, T& ,T*> iterator;
typedef iterator_list<T, const T&, const T*> const_iterator;

我们只需要关注第一个迭代器即可,因为第二个迭代器修饰的对象是不可以修改的。所以insert的实现代码如下:

	iterator insert(iterator pos, const T& x)//在pos位置之前插入新节点{Node* newnode = new Node(x);Node* prev = pos._node->prev;prev->next = newnode;newnode->prev = prev;newnode->next = pos._node;pos._node->prev = newnode;return pos._node->prev;//防止迭代器失效,所以返回pos的前一个位置}

检验一下,检验代码如下:

void test_list2(){list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);for (auto e : l1){cout << e << " ";}cout << endl;l1.insert(l1.begin(), 9);l1.insert(l1.end(), 99);for (auto e : l1){cout << e << " ";}cout << endl;}

结果:正确

 在实现了insert()函数以后便可以复用实现push_back()与push_front()。代码如下:

        void push_back(const T& val){insert(begin(), val);}void push_front(const T& val){insert(end(), val);}

2.erase()函数

erase()函数实现的功能便是传入一个位置,然后将该位置上的节点删除掉。代码实现如下:

       iterator erase(iterator pos){Node* prev = pos._node->prev;Node* next = pos._node->next;Node* cur = pos._node;delete cur;prev->next = next;next->prev = prev;return iterator(next);//返回新的迭代器}

复用erase实现尾删与头删,代码如下:

​void pop_back(){erase(--end());//尾巴是--end()的位置}void pop_front(){erase(begin());}​

实验代码:

void test_list3(){list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);for (auto e : l1){cout << e << " ";}cout << endl;l1.insert(l1.begin(), 9);l1.insert(l1.end(), 99);for (auto e : l1){cout << e << " ";}cout << endl;l1.pop_back();l1.pop_front();for (auto e : l1){cout << e << " ";}cout << endl;}

结果:正确

3.clear()与析构函数

实现了erase()函数以后再接再厉,接着复用实现clear函数,代码如下:

        void clear(){iterator it = begin();while (it != end()){it = erase(it);//erase()每次都会返回下一个位置}}

从上面代码的逻辑便可以看出clear()函数是不会删除掉头节点的。但是析构函数需要。于是复用clear()函数后析构函数代码如下:

       ~list(){clear();delete _head;}

4.拷贝构造函数赋值运算符重载

拷贝构造函数实现过程大概分三步,首先new出来一个空间。然后再复用push_back()函数将要赋值的数据拷贝到新节点内。实现代码如下:

	list(const list<T>& l1){empty();for (auto e : l1){push_back(e);}}

实现了拷贝构造以后,按照惯例,赋值也要被安排上了。赋值运算符重载实现代码如下:

     list<T>& operator =( list<T>& l1){if (this!= &l1){clear();for (auto e : l1){push_back(e);}}return *this;}

这是一个传统写法的运算符重载。如果想要更加精简可以写成现代写法,代码如下:

        void swap( list<T>& l1)//别加const{std::swap(_head, l1._head);//记得这个swap是std里面的swap}list<T>& operator=(list<T> l1){if (this != &l1){swap(l1);}return *this;}

5.打印函数

在这里,我们每次打印一个list对象时会很麻烦,每次都要用范围for来实现打印的功能。为了偷懒,我就想实现一个打印函数print来实现打印功能。实现代码如下:

template<class T>void print(list<T>& l1){typename list<T>::iterator it = l1.begin();//这里要用typename为前缀来告诉编译器等list<T>实例化以后再来执行这条语句for (auto e : l1){cout << e << " ";}cout << endl;}

但是上面的代码针对的类型时list类的泛型,如果想要实现能加载更多容器的print()函数那就得改一下类型,改为如下代码:

template <class Contains>void print(Contains& l1){typename Contains::iterator it = l1.begin();for (auto e : l1){cout << e << " ";}cout << endl;}

http://www.hkea.cn/news/285838/

相关文章:

  • 企业怎样选择域名做网站电脑突然多了windows优化大师
  • 网站一元空间有哪些呀品牌策划方案范文
  • 最便宜的网站建设企点
  • 网站代码加密深圳新闻今日最新
  • 不要钱做网站软件网站seo优化效果
  • 公司做网站提供产品加盟费互联网销售怎么做
  • 视频网站开发架构百度app最新版本
  • 网站上内容列表怎么做的网站模板中心
  • 上海利恩建设集团有限公司网站国内好用的搜索引擎
  • 网站模板论坛今日重大军事新闻
  • 昆山自适应网站建设电商平台的营销方式
  • 盘龙区网站建设外包高级搜索引擎技巧
  • 什么做的网站吗58百度搜索引擎
  • wordpress 企业站开发口碑营销的概念
  • 广州免费核酸检测点东莞seo项目优化方法
  • 学风建设网站版块设计个人网站
  • 网站底部连接怎么做福州seo推广
  • 生猪价格今日猪价行情关键词优化是什么工作
  • 网站建设公司下载搜索引擎查询
  • 韩国吃秀在哪个网站做直播企业宣传
  • 江西网站建设成都百度
  • 糯米团网站怎么做微信软文范例100字
  • 如何在社交网站上做视频推广seo营销的概念
  • 大连做网站仟亿科技最新域名查询
  • 网站开发实施计划与安排宁波网络推广方式
  • 企业网站建设公司注意哪些问题软件开发外包公司
  • abc网站建设怎么样yandex引擎搜索入口
  • wordpress屏蔽f12广州seo网络优化公司
  • 南宁网站建设推广服务云服务器免费
  • 大数据营销是什么seo站长