实现一个带头结点的双向带环链表:
观察这样一个链表(写出代码如下):
//List.h
#pragma once
#include <assert.h>
#include <iostream>
using namespace std;
template <class T>
struct ListNode
{
ListNode(T x)
:_prev(NULL)
,_next(NULL)
,_data(x)
{}
ListNode* _prev;
ListNode* _next;
T _data;
};
template <class T>
class List
{
typedef ListNode<T> Node;
public:
List()
:_head(new Node(T()))
{
_head->_next = _head;
_head->_prev = _head;
}
~List()
{
Node* cur = _head->_next;
while(cur != _head)
{
Node* todelete = cur;
cur = cur->_next;
delete todelete;
}
delete _head;
_head = NULL;
}
List(const List<T>& l);
List<T>& operator=(const List<T>& l);
void PushBack(T x);
void PushFront(T x);
void Insert(Node* pos, T x);
void PopFront();
void PopBack();
void Erase(Node* pos);
ListNode<T>* Front();
ListNode<T>* Back();
size_t Size();
int Empty();
void print();
protected:
Node* _head;
};
//List.cpp
#include <iostream>
#include "List.h"
template <class T>
void List<T>::Insert(Node* pos, T x)
{
assert(pos);
Node* pre = pos->_prev;
Node* new_node = new Node(x);
pre->_next = new_node;
new_node->_next = pos;
pos->_prev = new_node;
new_node->_prev = pre;
return;
}
template <class T>
void List<T>::PushBack(T x)
{
Insert(_head, x);
}
template <class T>
void List<T>::PushFront(T x)
{
Insert(_head->_next, x);
}
template <class T>
void List<T>::Erase(Node* pos)
{
assert(pos && pos != _head);
Node* prev = pos->_prev;
Node* next = pos->_next;
prev->_next = next;
next->_prev = prev;
delete pos;
}
template <class T>
void List<T>::PopFront()
{
Erase(_head->_next);
}
template <class T>
void List<T>::PopBack()
{
Erase(_head->_prev);
}
template <class T>
ListNode<T>* List<T>::Front()
{
return _head->_next;
}
template <class T>
ListNode<T>* List<T>::Back()
{
return _head->_prev;
}
template <class T>
size_t List<T>::Size()
{
Node* cur = _head->_next;
size_t count = 0;
while(cur != _head)
{
cur = cur->_next;
++count;
}
return count;
}
template <class T>
int List<T>::Empty()
{
return Size() == 0;
}
template <class T>
void List<T>::print()
{
Node* cur = _head->_next;
while(cur != _head)
{
cout<<cur->_data<<"->";
cur = cur->_next;
}
cout<<endl;
cur = _head->_prev;
while(cur != _head)
{
cout<<cur->_data<<"->";
cur = cur->_prev;
}
cout<<endl;
}
template <class T>
List<T>::List(const List<T>& l)
{
_head = new Node(T());
_head->_next = _head;
_head->_prev = _head;
Node* cur = l._head -> _next;
while(cur != l._head)
{
PushBack(cur->_data);
cur = cur->_next;
}
}
template <class T>
List<T>& List<T>::operator=(const List<T>& l)
{
if(this != &l)
{
Node* cur = _head->_next;
while(cur != _head)
{
Node* pre = cur->_prev;
Node* nex = cur->_next;
pre->_next = nex;
nex->_prev = pre;
delete cur;
cur = nex;
}
cur = (l._head)->_next;
while(cur != l._head)
{
PushBack(cur->_data);
cur = cur->_next;
}
}
return *this;
}