从C++开始的编程生活(13)——list和浅谈stack、queue
前言
本系列文章承接C语言的学习,需要有C语言的基础才能学会哦~
第13篇主要讲的是有关于C++的list和浅谈stack、queue。
C++才起步,都很简单!!
目录
list
基本用法
push_back()
emplace_back()
reverse( )
merge( )
unique( )
remove( )
splice( )
sort()
迭代器分类
list的模拟实现
stack和queue
list
底层结构是带头双向循环链表,也是一种顺序容器。
因为是带头双向循环,所以其迭代器end()指向的是哨兵位,begin()是哨兵位下一个。
基本用法
push_back()
list<pos> lt;
pos p1(1,1);
lt.push_back(p1);
lt.push_back(pos(2,2);
lt.push_back({3,3});
push_back的参数必须是对应的类型,这里是pos,传入的必须为pos,第三个push_back为隐式类型转换。
emplace_back()
lt.emplace_back(p1);
lt.emplace_back(pos(2, 2));
lt.emplace_back(3, 3);
和push_back用法类似,但是第三行情况下emplace_back更高效(看编译器怎么优化)。
reverse( )
反转链表。
merge( )
合并已经排序的链表,括号内的链表会变为空。
unique( )
去重,只能对已经排序的链表使用。
remove( )
移除,相当于find()再erase(),但是find不到也不会报错。
splice( )
接合,取一链表或者该链表的一段或者该链表中的一项,粘贴到另一个链表或者改链表的其他位置中,粘贴源被删除。
sort()
排序,list特有的,vector排序可以调用std库的sort,但是list不能用标准库里的sort。这里涉及了迭代器类别的问题。但是list.sort()排序的性能比较低,数据少或者排序情况少的时候可以用一下。
迭代器分类
| 分类 | 功能 | 常见于容器 |
| 单向迭代器 | ++ | forward_list,unorder_xxx |
| 双向迭代器 | ++/-- | list |
| 随机迭代器 | ++/--/+/- | string/vector |
不同的容器,其迭代器有所不同,功能也有所不同,如果让函数中的迭代器执行功能之外的操作,就会报错。
三者的根据功能,具有包含与被包含关系。
list的模拟实现
#pragma once
#include<assert.h>
#include<iostream>
namespace bit
{template<class T>struct listNode{//都是公有public,因为各种操作需要访问这些指针T _data;listNode<T>* _next;listNode<T>* _prev;list_node(const T& x = T()):_data(x), _next(nullptr), _prev(nullptr){}};template<class T, class Ref, class Ptr>struct list_iterator{typedef list_node<T> Node;typedef list_iterator<T, Ref, Ptr> Self;Node* _node;list_iterator(Node* node):_node(node){}Ref operator*(){return _node->_data;}//前置Self& operator++(){_node = _node->_next;return *this;}Self& operator--(){_node = _node->_prev;return *this;}//后置Self& operator++(int){Self tmp(*this);_node = _node->_next;return tmp;}Self& operator--(int){Self tmp(*this);_node = _node->_prev;return tmp;}Ptr operator->(){return &_node->_data;}bool operator!=(const Self& s){return _node != s._node;}bool operator==(const Self& s){return _node == s._node;}};//template<class T>//struct list_const_iterator//{// typedef list_node<T> Node;// typedef list_const_iterator<T> Self;// Node* _node;// list_const_iterator(Node* node)// :_node(node)// {}// const T& operator*()// {// return _node->_data;// }// //前置// Self& operator++()// {// _node = _node->_next;// return *this;// }// Self& operator--()// {// _node = _node->_prev;// return *this;// }// //后置// Self& operator++(int)// {// Self tmp(*this);// _node = _node->_next;// return tmp;// }// Self& operator--(int)// {// Self tmp(*this);// _node = _node->_prev;// return tmp;// }// const T& operator->()// {// return &_node->_data;// }// bool operator!=(const Self& s)// {// return _node != s._node;// }//};//一个用class,一个用struct,是因为一个类既有公有又有私有,我们就用class,反之用struct。// 这是一个惯例,不这样做效果也一样template<class T>class list{typedef listNode<T> Node;public:typedef list_iterator<T, T&, T*> iterator;typedef const list_iterator<T, const T&, const T*> const_iterator;iterator begin(){return iterator(_head->_next);}iterator end(){return iterator(_head);}const_iterator begin() const{return iterator(_head->_next);}const_iterator end() const{return iterator(_head);}~list(){clear();delete _head;_head = nullptr;}void swap(list<T>& tmp){std::swap(_head, tmp._head);}void clear(){auto it = begin();while (it != end()){erase(it);}}void empty_init(){_head = new Node();_head->_next = _head;_head->_prev = _head;_size = 0;}list(){empty_init();}list(const list<T>& lt){empty_init();for (auto& e : lt){push_back(e);}}list<T>& operator=(list<T> lt){swap(lt);return *this;}list(size_t n, cosnt T& val = T()){empty_init();for (size_t i = 0; i < n; i++){push_back({ 3,3 });}}void push_back(const T& x){//Node* new_node = new Node(x);//Node* tail = _head->prex;//_tail->_next = new_node;//new_node->prec = tail;//new_node->_next = _head;//_head->_prev = new_node;insert(end(), x);}void push_front(const T& x){insert(begin(),x)}iterator insert(iterator pos, const T& val){Node* cur = pos._node;Node* newnode = new Node(val);Node* prev = cur->_prev;prev->_next = newnode;newnode->prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++;return iterator(newnode);}iterator erase(){Node* del = pos._node;Node* prev = del->_prev;Node* next = del->_next;prev->_next = next;next->_prev = prev;delete del;--_size;}private:Node* _head;size_t _size;};
}
stack和queue
栈和队列,是容器适配器(之后会深入讲)。
其成员函数与其他的STL容器都十分类似。特别的是,这两者没有迭代器。
❤~~本文完结!!感谢观看!!接下来更精彩!!欢迎来我博客做客~~❤
