双向循环链表的概念想必大家应该比我清楚呵,在此不多说,主要想总结一下我在编程过程中的两点经验:
第一,如果在链表中插入时仅仅指出直接前驱结点,钩链时必须注意先后次序是: “先右后左”。部分语句组如下:
L= new LNode();
L->val=e;
L->next=p->next; p->next->prev=L;
p->next=L; L->prev=p; /* 钩链次序非常重要 */
而如果插入时同时指出直接前驱结点p和直接后继结点q,钩链时无须注意先后次序。部分语句组如下:
L= new LNode();
L->val=e;
p->next=S; L->next=q;
L->prev=p; q->prev=L;
第二,若List类中有成员函数返回的是在List类中定义的LIterator类型,那么必须在返回类型前加上typename,否则会出现编译错误:“error C4430: 缺少类型说明符”,这主要是因为LIterator有可能是类的数据成员或static成员,因此编译器不会默认为是类类型。部分语句组如下:
template <class T>
typename MyList<T>::LIterator MyList<T>::insert(LIterator& it, const T& t)
{
LNode* temp = it.node->prev;
temp = temp->next = new LNode(t, temp, it.node);
it.node = it.node->prev;++_size;
LIterator LIter(temp);
return LIter;
}
源代码如下:<MyList.h>
template <class T>
class MyList
{
protected:
class LNode
{
public:
LNode(const T& t = T(), LNode* p = 0, LNode* n = 0):val(t), prev(p), next(n)
{
if (prev == 0) prev = this;
if (next == 0) next = this;
}
T val;
LNode* prev, *next;
};
public:
class LIterator
{
public:
friend class MyList<T>;
LIterator() {}
LIterator(LNode* n) : node(n){}
LIterator(const LIterator& L) : node(L.node) {}
~LIterator() {}
T& operator * () {return node->val;}
LIterator& operator = (const LIterator& it) {node = it.node;}
bool operator == (const LIterator& it) {return it.node == node;}
bool operator != (const LIterator& it) {return it.node != node;}
LIterator operator ++ (int) // 后缀iter++
{
LIterator it(node);
node = node->next;
return it;
}
LIterator& operator ++ () // 前缀++iter
{
node = node->next;
return *this;
}
LIterator operator -- (int)
{
LIterator it(node);
node = node->prev;
return it;
}
LIterator& operator -- ()
{
node = node->prev;
return *this;
}
protected:
private:
LNode* node;
};
MyList();
MyList(const MyList& L);
MyList(int n);
MyList(int n, const T& t);
MyList(LIterator& first, LIterator& last);
~MyList();
MyList& operator = (const MyList& L);
int getSize() const {return _size;}
bool empty() const {return _size == 0;}
T& front();
T& back();
LIterator begin();
LIterator end(); //返回虚拟头指针,不指向任何有效元素
void push_front(const T& t);
void push_back(const T& t);
void pop_front();
void pop_back();
LIterator insert(LIterator& it, const T& t);
LIterator insert(LIterator& it, int n, const T& t);
void erase(LIterator& it);
void erase(LIterator& first, LIterator& last);
void clear();
void splice(LIterator& it, MyList& list, LIterator& first);
private:
LNode* _head; //虚拟头指针
size_t _size;
};
template <class T> MyList<T>::MyList():_size(0)
{
_head = new LNode;
}
template <class T> MyList<T>::MyList(const MyList& list):_size(list._size)
{
_head = new LNode();
LNode* temp = _head;
for (LNode* p = list._head->next; p != list._head; p = p->next)
{
temp = temp->next = new LNode(p->val, temp, _head);
}
_head->prev = temp;
}
template <class T> MyList<T>::MyList(int n):_size(n)
{
_head = new LNode;
LNode* temp = _head;
for (int i = 0; i < n; i ++)
{
temp = temp->next = new LNode(T(), temp, _head);
}
}
template <class T> MyList<T>::MyList(int n, const T& t):_size(n)
{
_head = new LNode();
LNode* temp = _head;
for (int i = 0; i < n; i ++)
{
temp = temp->next = new LNode(t, temp, _head); //往temp和head中间插入新节点
}
_head->prev = temp;
}
template <class T> MyList<T>::MyList(LIterator& first, LIterator& last)
{
_head = new LNode;
LNode* temp = _head;
for (LIterator p = first; first != last; last ++)
{
temp = temp->next = new LNode(p.node->val, temp, _head);
++_size;
}
}
template <class T> MyList<T>::~MyList()
{
LNode* temp = _head->next;
while (temp != _head)
{
LNode* p = temp;
temp = temp->next;
delete p;
}
delete _head;
}
template <class T> MyList<T>& MyList<T>::operator = (const MyList& L) : _size(L._size)
{
clear();
_head = new LNode;
LNode* temp = _head;
LNode* p = L._head->next;
while (p != L._head)
{
temp = temp->next = new LNode(p->val, temp, _head);
p = p->next;
}
}
template <class T> T& MyList<T>::front()
{
return _head->next->val;
}
template <class T> T& MyList<T>::back()
{
return _head->prev->val;
}
template <class T> typename MyList<T>::LIterator MyList<T>::begin() //注意:这里必须加typename,否则VC无法编译通过!
{
LIterator temp(_head->next);
return temp;
}
template <class T> typename MyList<T>::LIterator MyList<T>::end()
{
LIterator temp(_head);
return temp;
}
template <class T> void MyList<T>::push_front(const T& t)
{
_head->next = _head->next->prev = new LNode(t, _head, _head->next);
++_size;
}
template <class T> void MyList<T>::push_back(const T& t)
{
LNode* temp = _head->prev;
temp = temp->next = new LNode(t, temp, _head); //这里往temp和head中间插入新节点,也可以相反
_head->prev = temp;
++_size;
}
template <class T> void MyList<T>::pop_front()
{
if (_size > 0)
{
LNode* temp = _head->next;
_head->next = temp->next;
temp->next->prev = _head;
delete temp;
--_size;
}
return ;
}
template <class T> void MyList<T>::pop_back()
{
if (_size > 0)
{
LNode* temp = _head->prev;
_head->prev = temp->prev;
temp->prev->next = _head;
delete temp;
--_size;
}
return ;
}
template <class T>
typename MyList<T>::LIterator MyList<T>::insert(LIterator& it, const T& t) //在it前插入元素
{
LNode* temp = it.node->prev;
temp = temp->next = new LNode(t, temp, it.node);
it.node = it.node->prev;
++_size;
LIterator LIter(temp);
return LIter;
}
template <class T>
typename MyList<T>::LIterator MyList<T>::insert(LIterator& it, int n, const T& t)
{
LNode* p = it.node;
LNode* q = p->prev;
for (int i = 0; i < n; i ++)
{
q = q->next = new LNode(t, q, p);
++_size;
}
p->prev = q;
it.node = p;
LIterator LIter(p);
return LIter;
}
template <class T>
void MyList<T>::erase(LIterator& it)
{
if (_size == 0) return;
LNode* temp = it.node;
temp->prev->next = temp->next;
temp->next->prev = temp->prev;
it.node = temp->next;
delete temp;
--_size;
}
template <class T>
void MyList<T>::erase(LIterator& first, LIterator& last) //last不会被删除
{
first.node->prev->next = last.node;
last.node->prev = first.node->prev;
LNode* temp = first.node;
LNode* p = first.node->next;
while (temp != last.node)
{
delete temp;
temp = p;
p = p->next;
--_size;
}
}
template <class T>
void MyList<T>::clear()
{
while (_head->next != _head)
{
pop_back();
}
}
template <class T>
void MyList<T>::splice(LIterator& it, MyList& L, LIterator& first) //从其他list中抽取元素first至it前
{
LNode* p = it.node;
LNode* q = first.node;
q->prev->next = q->next; //先将first断开
q->next->prev = q->prev;
q->prev = p; //再将first与it连接,原则:先右后左
q->next = p->next;
p->next->prev = q;
p->next = q;
++_size;
--L._size;
}