1.list.h头文件
#pragma once
#include<assert.h>
namespace my
{
template<class T>
struct list_node
{
list_node<T>* _next;
list_node<T>* _prev;
T _val;
list_node(const T& val = T())
:_next(nullptr)
,_prev(nullptr)
,_val(val)
{}
};
struct A
{
A(int a1=0,int a2=0)
:a1(a1)
,a2(a2)
{}
int a1;
int a2;
};
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->_val;
}
self& operator++()
{
_node= _node->_next;
return *this;
}
self& operator--()
{
_node = _node->_prev;
return *this;
}
Ptr operator->()
{
return &(_node->_val);
}
self operator++(int)
{
self tmp(*this);
_node = _node->_next;
return tmp;
}
self operator--(int)
{
self tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator!=(const self& it)
{
return _node != it._node;
}
bool operator==(const self& it)
{
return _node == it._node;
}
};
template<class T>
class list
{
typedef list_node<T> Node;
public:
typedef _list_iterator<T,T&,T*> iterator;
typedef _list_iterator<T, const T&,const T*> const_iterator;
list()
{
_head = new Node;
_head->_prev = _head;
_head->_next = _head;
}
//拷贝构造
list(const list<T>& li)
{
_head = new Node;
_head->_prev = _head;
_head->_next = _head;
for (auto& e : li)
{
push_back(e);
}
}
//赋值
void swap(list<T>& li)
{
std::swap(_head, li._head);
}
list<T>& operator=(list<T> li)
{
swap(li);
return *this;
}
~list()
{
clear();
delete _head;
_head = nullptr;
}
void clear()
{
iterator it = begin();
while (it != end())
{
it = erase(it);
}
}
size_t size()
{
size_t sz = 0;
iterator it = begin();
while (it != end())
{
++sz;
++it;
}
return sz;
}
iterator begin()
{
return _head->_next;
}
iterator end()
{
return _head;
}
const_iterator begin() const
{
return _head->_next;
}
const_iterator end() const
{
return _head;
}
void push_back(const T& x)
{
Node* tail = _head->_prev;
Node* newnode = new Node(x);
tail->_next = newnode;
newnode->_prev = tail;
newnode->_next = _head;
_head->_prev = newnode;
//insert(end(),x)
}
void push_front(const T& x)
{
insert(begin(), x);
}
void pop_back()
{
erase(--end());
}
void pop_front()
{
erase(begin());
}
//在pos之前
iterator insert(iterator pos,const T& x)
{
Node* cur = pos._node;
Node* prev = cur->_prev;
Node* newnode = new Node(x);
prev->_next = newnode;
newnode->_next = cur;
cur->_prev = newnode;
newnode->_prev = prev;
return newnode;
}
iterator erase(iterator pos)
{
assert(pos != end());
Node* cur = pos._node;
Node* prev = cur->_prev;
Node* next = cur->_next;
prev->_next = next;
next->_prev = prev;
delete cur;
return next;
}
private:
Node* _head;
};
void print(const list<int>& li)
{
list<int >::const_iterator it = li.begin();
while (it != li.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
void list_text1()
{
list<int >li;
li.push_back(1);
li.push_back(2);
li.push_back(3);
li.push_back(4);
list<int >::iterator it = li.begin();
while (it != li.end())
{
cout << *it << " ";
++it;
}
cout << endl;
print(li);
}
void list_text2()
{
list<A>li;
li.push_back(A(1,1));
li.push_back(A(2,2));
li.push_back(A(3,3));
li.push_back(A(4,4));
list<A>::iterator it = li.begin();
while (it != li.end())
{
//it->调用operator->返回A*,严格来说it->->a1,才是正确的,这里编译器做了优化,省略了一个->
cout << it->a1 << " " << it->a2 << endl;
++it;
}
cout << endl;
}
void list_text3()
{
list<int >li;
li.push_back(1);
li.push_back(2);
li.push_back(3);
li.push_back(4);
li.push_front(5);
li.push_front(5);
li.push_front(5);
li.push_front(5);
li.push_back(6);
li.push_back(6);
li.push_back(6);
li.push_back(6);
for (auto e : li)
{
cout << e << " ";
}
cout << endl;
li.pop_back();
li.pop_front();
for (auto e : li)
{
cout << e << " ";
}
cout << endl;
li.clear();
li.push_back(1);
li.push_back(2);
li.push_back(3);
li.push_back(4);
for (auto e : li)
{
cout << e << " ";
}
cout << endl;
cout << li.size() << endl;
}
void list_text4()
{
list<int >li;
li.push_back(1);
li.push_back(2);
li.push_back(3);
li.push_back(4);
list<int> li1(li);
for (auto e : li1)
{
cout << e << " ";
}
cout << endl;
list<int> li2;
li2 = li1;
for (auto e : li2)
{
cout << e << " ";
}
cout << endl;
cout << li2.size() << endl;
for (auto e : li1)
{
cout << e << " ";
}
cout << endl;
}
}