本文模擬實現了c++標準模板庫中的List。 它的底層實現是一個帶頭結點的雙向循環鏈表。
一個注意要點是,不同於vector和string的迭代器的封裝
typedef T* Iterator
List 採用了一個類來封裝迭代器
//list迭代器的封裝
template <class T, class Ref, class Ptr>
struct ListIterator
{
typedef ListIterator <T, Ref, Ptr> Self;
ListNode<T>* _node;
ListIterator(ListNode<T>* node)
: _node(node)
{}
Ref operator*()
{
return _node->_data;
}
Ptr 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;
}
bool operator !=(const Self& lit)
{
return _node != lit._node;
}
bool operator==(const Self& lit)
{
return _node == lit._node;
}
};
然後在List類中進行typedef
template <class T>
class List
{
public:
typedef ListNode<T> Node;
typedef ListIterator<T, T&, T*> iterator;
typedef const ListIterator<T, T&, T*> const_iterator;
typedef Node* pNode;
OK,迭代器的實現在這裏強調一下。剩下的都不難理解。
下面給出List的模擬實現:
//模擬實現STL---list :帶頭結點的循環雙向鏈表
namespace tonglin{ //命名空間
template <class T>
struct ListNode
{
ListNode(const T& val = T())
: _data(val)
, _next(nullptr)
, _prev(nullptr)
{}
T _data;
ListNode<T>* _next;
ListNode<T>* _prev;
};
//list迭代器的封裝
template <class T, class Ref, class Ptr>
struct ListIterator
{
typedef ListIterator <T, Ref, Ptr> Self;
ListNode<T>* _node;
ListIterator(ListNode<T>* node)
: _node(node)
{}
Ref operator*()
{
return _node->_data;
}
Ptr 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;
}
bool operator !=(const Self& lit)
{
return _node != lit._node;
}
bool operator==(const Self& lit)
{
return _node == lit._node;
}
};
template <class T>
class List
{
public:
typedef ListNode<T> Node;
typedef ListIterator<T, T&, T*> iterator;
typedef const ListIterator<T, T&, T*> const_iterator;
typedef Node* pNode;
//List的構造函數
List()
{
cout << "Constructor called!" << endl;
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
}
//拷貝構造函數,要實現深拷貝
List(const List& lst)
{
//先創建頭節點
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
//再將數據賦進去
for (const auto &e : lst)
{
PushBack(e);
}
}
//析構函數
~List()
{
cout << "destructor called!" << endl;
Clear();
if (_head)
{
delete _head;
_head = nullptr;
}
}
//賦值運算符重載
List<T>& operator=(const List<T> lst)
{
/*if (this != &lst)
{
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
for (const auto& e : lst)
{
PushBack(e);
}
}
return *this;*/
swap(_head, lst._head);
return *this;
}
///////////////////////////////
//////////華麗分割/////////////
///////////////////////////////
iterator begin()
{
return iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
const_iterator begin() const
{
return const_iterator(_head->_next);
}
const_iterator end() const
{
return const_iterator(_head);
}
//尾插
void PushBack(const T& val)
{
pNode newNode = new Node(val); //創建新節點 -》 prev和next賦值 -》(對有所影響的數據項做更改) 之前的最後一個節點的next更新爲newnode -》head的prev更新
newNode->_next = _head;
newNode->_prev = _head->_prev;
newNode->_prev->_next = newNode;
_head->_prev = newNode;
}
//尾刪
void PopBack()
{
//先找到最後一個節點
pNode pDel = _head->_prev;
if (pDel != _head)
{
//如果不是空鏈表,那麼就對刪除後有影響的數據項做以修改
pDel->_prev->_next = _head;
_head->_prev = pDel->_prev;
delete pDel;
}
else
return;
}
//頭插
void PushFront(const T& val)
{
//若還沒有有效節點,則就是尾插
if (isEmpty())
{
PushBack(val);
}
else
{
pNode newNode = new Node(val);
_head->_next->_prev = newNode;
newNode->_next = _head->_next;
_head->_next = newNode;
newNode->_prev = _head;
}
}
//頭刪
void PopFront()
{
//若沒有有效節點
if (isEmpty())
{
cout << "刪除失敗!" << endl;
}
else
{
//找到要刪除的節點
pNode pDel = _head->_next;
_head->_next = pDel->_next;
pDel->_next->_prev = pDel->_prev;
delete pDel;
}
}
//在pos位置前插入節點
void Insert(iterator pos, const T& val)
{
pNode newNode = new Node(val);
pNode cur = pos._node;
newNode->_prev = cur->_prev;
newNode->_prev->_next = newNode;
newNode->_next = cur;
cur->_prev = newNode;
}
//刪除pos位置的節點,返回該節點的下一個位置
iterator Erase(iterator pos)
{
//不能刪除頭結點
if (pos != end())
{
pNode cur = pos._node;
cur->_prev->_next = cur->_next;
cur->_next->_prev = cur->_prev;
//更新迭代器
pos = iterator(cur->_next);
delete cur;
}
return pos;
}
void Clear()
{
//清空,即保留頭節點,刪除其他所有有效節點
pNode cur = _head->_next;
while (cur != _head)
{
_head->_next = cur->_next;
delete cur;
cur = _head->_next;
}
_head->_next = _head;
_head->_prev = _head;
}
//獲取節點個數
size_t Size() const
{
size_t count = 0;
pNode cur = _head->_next;
while (cur != _head)
{
++count;
cur = cur->_next;
}
return count;
}
bool isEmpty()
{
return _head->_next == _head;
}
void printList()
{
auto lit = this->begin();
while (lit != this->end())
{
cout << *lit << " ";
++lit;
}
cout << endl;
}
private:
pNode _head;
};
}//end of namespace:tongin