一、vector
vector像一个容器一样可以存放各种类型的对象,它是一个能够存放任意类型的动态数组,能够增加和压缩数据。使用vector,需要在头文件中包含#include <vector>
1、简单模拟实现vector:
void print_vector(const vector<int>& v)//迭代器失效
{
vector<int>::const_iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
void test_vector1()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
print_vector(v1);
//解决迭代器的失效
vector<int>::iterator it1 = v1.begin();
while (it1 != v1.end())
{
if (*it1 % 2 == 0)
{
it1 = v1.erase(it1);
}
else
{
++it1;
}
}
print_vector(v1);
vector<int>::iterator pos1 = find(v1.begin(), v1.end(), 3);
v1.insert(pos1, 5);
print_vector(v1);
pos1 = find(v1.begin(), v1.end(), 3);
v1.erase(pos1);
print_vector(v1);
}
template<class T>
class Vector
{
public:
typedef T* Iterator;
Vector()
:_start(NULL)
, _finish(NULL)
, _endOfStorage(NULL)
{}
Vector(int n, const T* data = T())
:_start(NULL)
, _finish(NULL)
, _endOfStorage(NULL)
{
_start = new T(n);
for (size_t i = 0; i < n; ++i)
{
_start[i] = data;
}
_finish = _start + n;
_endOfStorage = _finish;
}
Vector(const vector<T>& v)
:_start(NULL)
, _finish(NULL)
, _endOfStorage(NULL)
{
size_t size = Size();
v.size = new T[size];
for (size_t i = 0; i < size; ++i)
{
v._start[i] = _start;
}
_finish = _start + size;
_endOfStorage = _finish;
}
~Vector()
{
if (_start)
{
delete[] _start;
_start = _finish = _endOfStorage = NULL;
}
}
void Resize(size_t n, const T& val = T())
{
if (n > Capacity())
{
Expand(n);
}
size_t size = Size();
if (n < size)
{
_finish = _start + n;
}
else
{
for (size_t i = 0; i < n - _size, ++i)
{
PushBack(val);
}
}
}
void Reserve(size_t n)
{
Expend(n);
}
void PopBack()
{
assert(_finish > _start);
--_finish;
}
void PushBack(const T& x)
{
if (_finish == _endOfStorage)
{
size_t capacity = Capacity();
size_t n = capacity == 0 ? 3 : 2 * capacity;
Expand(n);
}
*_finish = x;
++_finish;
}
Iterator Begin()
{
return _start;
}
Iterator End()
{
return _finish;
}
size_t Capacity()
{
return _endOfStorage - _start;
}
size_t Size()
{
return _finish - _start;
}
void Expand(size_t n)
{
size_t capacity = Capacity();
size_t size = Size();
if (n > capacity)
{
T* tmp = new T[n];
for (size_t i = 0; i < size; ++i)
{
tmp[i] = _start[i];
}
delete[] _start;
_start = tmp;
_finish = _start + size;
_endOfStorage = _start + n;
}
}
T& operator[](size_t index)
{
assert(index < Size());
return _start[index];
}
//重载
const T& operator[](size_t index)const
{
assert(index < Size());
return _start[index];
}
protected:
Iterator _start;
Iterator _finish;
Iterator _endOfStorage;
};
2、这里着重说明一下vector的成员函数resize和 reserve的作用和区别:
(1)、reserve与capacity息息相关,当reserve(n),n>capacity,将capacity增容到n,否则不变;resize与size息息相关,resize(n),size变为n,而capacity是否改变取决于n是否大于capacity。
(2)、reserve()增容是先增容,再将以前的数据拷过去,不断重复,不断扩大,代价大,因此使用reserve()函数会提前设定容量大小,只要不超过它的最大容量,它可以自动增长以容纳你的所有数据;而resize()可以直接增容到想要的空间。
(3)、reserve()搭配push_back()顺序插入数据;resize()搭配operator[]可以初始化和随机插入。
他们的共同作用是减少增容,提高vector的效率。
二、list
list是标准STL中的序列式容器,它里面的元素是有序的线性序列,可以进行快速的插入删除,可以存放任何数据类型,包括指针,但是不支持随机访问。list是一个双向循环列表,其中的元素通过迭代器遍历。
简单模拟实现list:
#pragma once
#include <cassert>
#include <list>
#include <iostream>
using namespace std;
template <class T>
struct ListNode//链表节点
{
T _data;
ListNode<T>* _prev;
ListNode<T>* _next;
ListNode(const T& data)
:_data(data)
, _prev(NULL)
, _next(NULL)
{}
};
template<class T,class Ref,class Ptr>
struct _ListIterator//正向迭代器
{
typedef ListNode<T> Node;
typedef _ListIterator<T, Ref, Ptr> Self;
typedef Ref Refrence;
typedef Ptr Pointer;
_ListIterator(Node* x)
:_node(x)
{}
Ref& operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &(operstor*())
}
Self& operator++()
{
_node = _node->_next;
return *this;
}
Self operator++(int)
{
Self tmp(*this);
_node = _node->_next;
return tmp;
}
Self& operator--()
{
_node = _node->_prev;
return *this;
}
Self operator--(int)
{
Self tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator !=(const Self& s)
{
return _node != s._node;
}
bool operator ==(const Self& s)
{
return _node == s._node;
}
Node* _node;
};
template<class T>
class List
{
typedef ListNode<T> Node;
public:
typedef _ListIterator<T, T&, T*>Iterator;
typedef _ListIterator<T, const T&, const T*>constIterator;
Node* BuyNode(const T& x)//构造新节点
{
return new Node(x);
}
List()//带头节点的双向链表
{
_head = BuyNode(T());
_head->_next = _head;
_head->_prev = _head;
}
void Clear()
{
Iterator it = Begin();
if (it != End())
{
Node* del = it._node;
++it;
delete del;
}
_head->_next = _head;
_head->_prev = _head;
}
~List()
{
Clear();
delete _head;
_head = NULL;
}
Iterator Begin()
{
return Iterator(_head->_next);
}
Iterator End()
{
return Iterator(_head);
}
Iterator Begin() const
{
return constIterator(_head->_next);
}
Iterator End() const
{
return constIterator(_head);
}
Iterator Find(const T& x)
{
Iterator it = Begin();
while (it != End())
{
if (*it == x)
{
return it;
}
else
{
++it;
}
}
return End();
}
void Insert(Iterator& pos, const T& x)
{
assert(pos._node);
Node* tmp = BuyNode(x);
Node* cur = pos._node;
Node* prev = cur->_prev;
prev->_next = tmp;
tmp->_next = cur;
cur->_prev = tmp;
tmp->_prev = prev;
}
Iterator Erase(Iterator pos)
{
assert(!Empty()&&pos._node);
Node* cur = pos._node;
Node* prev = cur->_prev;
Node* next = cur->_next;
delete cur;
prev->_next = next;
next->_prev = prev;
return next;//返回下一个位置
}
bool Empty()//判断链表是否为空
{
return _head == _head->_next;
}
void PushBack(const T& x)
{
Insert(End(), x);
}
void PopBack()
{
Erase(--End());
}
void PushFront(const T& x)
{
Insert(Begin(), x);
}
void PopFront()
{
Erase(Begin());
}
void Assign(size_t n, const T& val)
{
Clear();
for (size_t i = 0; i < n; ++i)
{
PushBack(val);
}
}
template <class InputIterator>
void Assign(InputIterator first, InputIterator last)
{
Clear();
while (first != last)
{
PushBack(*first);
++first;
}
}
private:
Node* _head;
Node* _prev;
Node* _next;
};
void Print(List<int>& l)//封装打印函数
{
List<int>::Iterator it = l.Begin();
while (it != l.End())
{
cout << *it << " ";
++it;
}
cout << endl;
}
void TestList()//测试代码
{
List<int> l;
l.PushBack(1);
l.PushBack(2);
l.PushBack(3);
l.PushBack(4);
Print(l);
//l.PopBack();
//l.PopBack();
//l.PushFront(9);
//l.PushFront(8);
//l.PopFront();
List<int>::Iterator it1 = l.Begin();
while (it1 != l.End())
{
if (*it1 % 2 == 0)
{
it1 = l.Erase(it1);
}
else
{
++it1;
}
cout << endl;
}
Print(l);
List<int> l1;
l1.Assign(l.Begin(), l.End());
Print(l1);
}