📘北尘_ :个人主页
🌎个人专栏 :《Linux操作系统》 《经典算法试题 》 《C++》 《数据结构与算法》
??走在路上,不忘来时的初心
一、 list的介绍
list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。 list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。 list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)
二、list的模拟实现
1、list的节点
template < class T >
struct list_node
{
T _data;
list_node< T> * _prev;
list_node< T> * _next;
list_node ( const T& x = T ( ) )
: _data ( x)
, _next ( nullptr )
, _prev ( nullptr )
{ }
} ;
2、list 的迭代器
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)
{ }
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;
}
Ref operator * ( )
{
return _node-> _data;
}
Ptr operator -> ( )
{
return & _node-> _data;
}
bool operator != ( const self& s)
{
return _node != s. _node;
}
bool operator == ( const self& s)
{
return _node == s. _node;
}
} ;
3、list
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;
iterator begin ( )
{
return _head-> _next;
}
iterator end ( )
{
return _head;
}
const_iterator begin ( ) const
{
return _head-> _next;
}
const_iterator end ( ) const
{
return _head;
}
void empty_init ( )
{
_head = new Node;
_head-> _next = _head;
_head-> _prev = _head;
_size = 0 ;
}
list ( )
{
empty_init ( ) ;
}
list ( list< T> & lt)
{
empty_init ( ) ;
for ( auto e : lt)
{
push_back ( e) ;
}
}
list< T> & operator = ( list< T> lt)
{
swap ( lt) ;
return * this ;
}
void swap ( list< T> lt)
{
std:: swap ( _size, lt. _size) ;
std:: swap ( _head, lt. _head) ;
}
iterator insert ( iterator pos, const T& x)
{
Node* cur = pos. _node;
Node* newnode = new Node ( x) ;
Node* prev = cur-> _prev;
prev-> _next = newnode;
newnode-> _prev = prev;
newnode-> _next = cur;
cur-> _prev = newnode;
++ _size;
return iterator ( newnode) ;
}
iterator erase ( iterator pos)
{
Node* cur = pos. _node;
Node* prev = cur-> _prev;
Node* next = cur-> _next;
delete cur;
prev-> _next = next;
next-> _prev = prev;
-- _size;
}
size_t size ( )
{
return _size;
}
void clear ( )
{
iterator it = begin ( ) ;
while ( it != end)
{
it = erase ( it) ;
}
}
void push_back ( const T& x)
{
insert ( end ( ) , x) ;
}
void push_front ( const T& x)
{
insert ( begin ( ) , x) ;
}
void push_back ( )
{
erase ( end ( ) ) ;
}
void pop_back ( )
{
erase ( begin ( ) ) ;
}
private :
Node* _head;
size_t _size;
} ;
4、打印
template < typename Container >
void print_container ( const Container& con)
{
typename Container :: const_iterator it = con. begin ( ) ;
while ( it != con. end ( ) )
{
cout << * it << " " ;
++ it;
}
cout << endl;
}
void test_list ( )
{
list< int > lt;
lt. push_back ( 1 ) ;
lt. push_back ( 2 ) ;
lt. push_back ( 3 ) ;
lt. push_back ( 4 ) ;
lt. push_back ( 5 ) ;
print_container ( lt) ;
list< string> lt1;
lt1. push_back ( "1111111111111" ) ;
lt1. push_back ( "1111111111111" ) ;
lt1. push_back ( "1111111111111" ) ;
lt1. push_back ( "1111111111111" ) ;
lt1. push_back ( "1111111111111" ) ;
print_container ( lt1) ;
vector< string> v;
v. push_back ( "222222222222222222222" ) ;
v. push_back ( "222222222222222222222" ) ;
v. push_back ( "222222222222222222222" ) ;
v. push_back ( "222222222222222222222" ) ;
print_container ( v) ;
}
}
int main ( )
{
bit:: test_list ( ) ;
return 0 ;
}
5、完整代码
# include <iostream>
# include <string>
# include <vector>
using namespace std;
namespace bit
{
template < class T >
struct list_node
{
T _data;
list_node< T> * _prev;
list_node< T> * _next;
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)
{ }
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;
}
Ref operator * ( )
{
return _node-> _data;
}
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 >
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;
iterator begin ( )
{
return _head-> _next;
}
iterator end ( )
{
return _head;
}
const_iterator begin ( ) const
{
return _head-> _next;
}
const_iterator end ( ) const
{
return _head;
}
void empty_init ( )
{
_head = new Node;
_head-> _next = _head;
_head-> _prev = _head;
_size = 0 ;
}
list ( )
{
empty_init ( ) ;
}
list ( list< T> & lt)
{
empty_init ( ) ;
for ( auto e : lt)
{
push_back ( e) ;
}
}
list< T> & operator = ( list< T> lt)
{
swap ( lt) ;
return * this ;
}
void swap ( list< T> lt)
{
std:: swap ( _size, lt. _size) ;
std:: swap ( _head, lt. _head) ;
}
iterator insert ( iterator pos, const T& x)
{
Node* cur = pos. _node;
Node* newnode = new Node ( x) ;
Node* prev = cur-> _prev;
prev-> _next = newnode;
newnode-> _prev = prev;
newnode-> _next = cur;
cur-> _prev = newnode;
++ _size;
return iterator ( newnode) ;
}
iterator erase ( iterator pos)
{
Node* cur = pos. _node;
Node* prev = cur-> _prev;
Node* next = cur-> _next;
delete cur;
prev-> _next = next;
next-> _prev = prev;
-- _size;
}
size_t size ( )
{
return _size;
}
void clear ( )
{
iterator it = begin ( ) ;
while ( it != end)
{
it = erase ( it) ;
}
}
void push_back ( const T& x)
{
insert ( end ( ) , x) ;
}
void push_front ( const T& x)
{
insert ( begin ( ) , x) ;
}
void push_back ( )
{
erase ( end ( ) ) ;
}
void pop_back ( )
{
erase ( begin ( ) ) ;
}
private :
Node* _head;
size_t _size;
} ;
template < typename Container >
void print_container ( const Container& con)
{
typename Container :: const_iterator it = con. begin ( ) ;
while ( it != con. end ( ) )
{
cout << * it << " " ;
++ it;
}
cout << endl;
}
void test_list ( )
{
list< int > lt;
lt. push_back ( 1 ) ;
lt. push_back ( 2 ) ;
lt. push_back ( 3 ) ;
lt. push_back ( 4 ) ;
lt. push_back ( 5 ) ;
print_container ( lt) ;
list< string> lt1;
lt1. push_back ( "1111111111111" ) ;
lt1. push_back ( "1111111111111" ) ;
lt1. push_back ( "1111111111111" ) ;
lt1. push_back ( "1111111111111" ) ;
lt1. push_back ( "1111111111111" ) ;
print_container ( lt1) ;
vector< string> v;
v. push_back ( "222222222222222222222" ) ;
v. push_back ( "222222222222222222222" ) ;
v. push_back ( "222222222222222222222" ) ;
v. push_back ( "222222222222222222222" ) ;
print_container ( v) ;
}
}
int main ( )
{
bit:: test_list ( ) ;
return 0 ;
}