前言
本系列文章承接C语言的学习,需要++有C语言的基础++ 才能学会哦~
第13篇主要讲的是有关于C++的++list++ 和++浅谈stack、queue++ 。
C++才起步,都很简单!!
目录
[reverse( )](#reverse( ))
[merge( )](#merge( ))
[unique( )](#unique( ))
[remove( )](#remove( ))
[splice( )](#splice( ))
list
底层结构是带头双向循环链表,也是一种顺序容器。
因为是带头双向循环,所以其迭代器++end()指向的是哨兵位++ ,++begin()是哨兵位下一个++。
基本用法
push_back()
cpp
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()
cpp
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的模拟实现
cpp
#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容器都十分类似。++特别的是,这两者没有迭代器++。
❤~~本文完结!!感谢观看!!接下来更精彩!!欢迎来我博客做客~~❤