双向链表(一口气写完)
#ifndef VLYFLIST_H_
#define VLYFLIST_H_
namespace vlyflist
{
//带头尾节点的双向链表
template <typename T>
class VlyfList
{
public:
friend class Iterator;
//双向节点
struct Node
{
Node(T& x) : data(x), prev(nullptr), next(nullptr) {}
T data;
Node* prev;
Node* next;
};
//迭代器
class Iteretor
{
public:
Iteretor(Node* node = nullptr) : current(node) {}
//前置++
Iteretor& operator++()
{
current = current->next;
return *this;
}
//后置++
Iteretor& operator++(int)
{
Iteretor tmp = *this;
++* this;
return tmp;
}
//前置--
Iteretor& operator--()
{
current = current->prev;
return *this;
}
//后置--
Iteretor& operator--(int)
{
Iteretor tmp = *this;
--* this;
return tmp;
}
//解引用
T& operator*() const
{
return current->data;
}
//==
bool operator==(const Iteretor& it) const
{
return current == it.current;
}
//!=
bool operator!=(const Iteretor& it) const
{
return current != it.current;
}
private:
Node* current; //当前所指数据
};
VlyfList() : theSize(0)
{
init();
}
VlyfList(const VlyfList& l)
{
init();
this->operator=(l);
}
~VlyfList()
{
Node* tmp = head->next;
Node* tmpnext = tmp->next;
while (tmp != tail)
{
delete tmp;
tmp = tmpnext;
tmpnext = tmp->next;
}
delete head;
delete tail;
}
//拷贝赋值
VlyfList& operator=(const VlyfList& l)
{
if (*this == l)
return *this;
else
{
for (auto it = this->begin(); it != this->end(); ++it)
push_back(*it);
}
return *this;
}
//==
bool operator==(const VlyfList& l)
{
return head == l.head && tail == l.tail && theSize == l.theSize;
}
//头插
void push_front(T& x)
{
insert(1, x);
}
//尾插
void push_back(T& x)
{
insert(size, x);
}
//访问第一个元素
T& front()
{
return *(begin());
}
const T& front() const
{
return *(begin());
}
//访问最后一个元素
T& back()
{
return *(--end());
}
const T& back() const
{
return *(--end());
}
//头删
void push_back()
{
Node* p = tail->prev;
p->prev->next = tail;
tail->prev = p->pre;
delete p;
theSize--;
}
//尾删
void push_front()
{
Node* p = head->next;
p->next->prev = head;
head->next = p->next;
delete p;
theSize--;
}
//删第i个节点
void deleteI(size_t i)
{
Node* p = head;
for (int i = 0; i < theSize; i++)
p = p->next;
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
theSize--;
}
//第一个节点迭代器
Iterator begin()
{
return Iteretor(head->next);
}
//tail的迭代器
Iterator end()
{
return Iteretor(tail);
}
//向第i个位置插入节点i>0,返回新节点的迭代器
Iteretor insert(unsigned i, T& x)
{
Node* p = head;
for (int i = 0; i < theSize; i++)
p = p->next;
Node* newnode = new Node(x, p->prev, p);
p->prev->next = newnode;
p->prev = newnode;
theSize++;
return Iteretor(newnode);
}
//链表初始化
void init()
{
head = new Node;
tail = new Node;
head->next = tail;
tail->prev = head;
}
size_t size() const { return theSize; }
bool empty() const { return theSize == 0; }
//迭代器
private:
Node* head;
Node* tail;
size_t theSize;
};
}
#endif
更新后的双向链表,上面的链表惨不忍睹,看看下面重构的吧
实在忍不住,模仿STL写了个阉割版的List,还没加迭代器,等搞完STL源码再说吧。
#pragma once
#include <stdexcept>
namespace vlyf
{
template <typename Key>
struct Node
{
using pointer = Node<Key>*;
Key key;
Node* prev{nullptr};
Node* next{nullptr};
Node() = default;
Node(Key const& k) : key(k) {}
};
template <typename T>
class List
{
private:
using linkType = Node<T>::pointer;
linkType head{new Node<T>};
public:
List()
{
head->prev = head;
head->next = head;
}
~List();
linkType Begin() const { return head->next; }
linkType End() const { return head; }
linkType Search(T const&) const;
linkType Erase(linkType position);
void Insert(linkType position, T const& x);
void PushBack(T const& x) { Insert(End(), x); }
void PushFront(T const& x) { Insert(Begin(), x); }
void PopFront() { Erase(Begin()); }
void PopBack()
{
linkType tmp = End()->prev;
Erase(tmp);
}
void Clear();
void Remove(T const& x);
void Unique();
void Delete(T const& x);
protected:
void Transfer(linkType position, linkType first, linkType last);
};
template <typename T>
inline List<T>::linkType List<T>::Search(T const& k) const
{
if (!head)
throw std::out_of_range("List is empty");
linkType p = head;
while (p->key != k)
{
p = p->next;
}
return p;
}
template <typename T>
inline void List<T>::Insert(List<T>::linkType position, T const& x)
{
linkType node = new Node<T>(x);
node->next = position;
node->prev = position->prev;
position->prev->next = node;
position->prev = node;
}
template <typename T>
inline void List<T>::Delete(T const& x)
{
if (!x->prev)
x->prev->next = x->next;
else
head->next = x->next;
if (!x->next)
x->next->prev = x->prev;
delete x;
}
template <typename T>
inline List<T>::linkType List<T>::Erase(List<T>::linkType position)
{
linkType nextNode = position->next;
linkType prevNode = position->prev;
prevNode->next = nextNode;
nextNode->prev = prevNode;
delete position;
return nextNode;
}
template <typename T>
inline void List<T>::Clear()
{
linkType cur = head->next;
while (cur != head)
{
linkType tmp = cur;
cur = cur->next;
delete tmp;
}
head->next = head;
head->prev = head;
}
template <typename T>
inline void List<T>::Remove(T const& x)
{
linkType first = Begin();
linkType last = End();
while (first != last)
{
linkType tmp = first;
tmp = tmp->next;
if (x == first->key)
{
Erase(first);
}
first = tmp;
}
}
template <typename T>
inline void List<T>::Unique()
{
linkType first = Begin();
linkType last = End();
if (first == last)
return;
linkType next = first->next;
while (next != last)
{
if (next->key == first->key)
Erase(next);
else
first = next;
next = first->next;
}
}
template <typename T>
inline void List<T>::Transfer(linkType position,
linkType first,
linkType last)
{
last->prev->next = position;
first->prev->next = last;
position->prev->next = first;
linkType tmp = postion->prev;
postion->prev = last->prev;
last->prev = first->prev;
first->prev = tmp;
}
} // namespace vlyf