#pragma once
#include <assert.h>
//template<class T>
//class List;
template<class T>
class Node
{
template<class T>
friend class List;
//friend class List<T>;
public:
Node(const T& x)
:_data(x)
, _next(NULL)
, _prev(NULL)
{}
private:
T _data; // 结点数据
Node<T>* _prev; // 指向前一个结点的指针
Node<T>* _next; // 指向后一个结点的指针
};
template<class T>
class List
{
public:
List()
:_head(NULL)
{}
~List()
{
Clear();
}
public:
// 头插/头删/尾插/尾删
void PushBack(const T& x);
void PopBack();
void PushFront(const T& x);
void PopFront();
// 插入/查找/删除
void Insert(Node<T>* pos, const T& x);
Node<T>* Find(const T& x);
void Erase(Node<T>* n);
void Reverse();
// 清除/打印
void Clear();
void Print();
private:
Node<T>* _head; // 指向链表头的指针
Node<T>* _tail; // 指向链表尾的指针
};
template<class T>
void List<T>::PushBack(const T& x)
{
// 1.没有节点
// 2.多个节点
if (_head == NULL)
{
_head = new Node<T>(x);
_tail = _head;
}
else
{
Node<T>* tmp = new Node<T>(x);
_tail->_next = tmp;
tmp->_prev = _tail;
_tail = tmp;
}
}
template<class T>
void List<T>::PopBack()
{
// 1.没有节点
// 2.一个节点
// 3.多个节点
if (_head == NULL)
{
return;
}
else if (_head == _tail)
{
delete _head;
_head = NULL;
_tail = NULL;
}
else
{
Node<T>* del = _tail;
_tail = _tail->_prev;
_tail->_next = NULL;
delete del;
}
}
template<class T>
void List<T>::PushFront(const T& x)
{
// 1.没有节点
// 2.多个节点
if (_head == NULL)
{
_head = new Node<T>(x);
_tail = _head;
}
else
{
Node<T>* tmp = new Node<T>(x);
tmp->_next = _head;
_head->_prev = tmp;
_head = tmp;
}
}
template<class T>
void List<T>::PopFront()
{
// 1.没有节点
// 2.一个节点
// 3.多个节点
if (_head == NULL)
{
return;
}
else if (_head == _tail)
{
delete _head;
_head = NULL;
_tail = NULL;
}
else
{
Node<T>* del = _head;
_head = _head->_next;
_head->_prev = NULL;
delete del;
}
}
template<class T>
void List<T>::Insert(Node<T>* pos, const T& x)
{
assert(pos);
Node<T>* tmp = new Node<T>(x);
// 1.若pos位置是尾节点,插入节点并更新尾。
if (pos == _tail)
{
pos->_next = tmp;
tmp->_prev = pos;
_tail = tmp;
return;
}
// 2.在当前节点后面插入一个节点,并更新前后指针,注意更新顺序。
Node<T>* next = pos->_next;
tmp->_next = next;
next->_prev = tmp;
pos->_next = tmp;
tmp->_prev = pos;
}
template<class T>
Node<T>* List<T>::Find(const T& x)
{
Node<T>* begin = _head;
while (begin)
{
if (begin->_data == x)
{
return begin;
}
begin = begin->_next;
}
return NULL;
}
template<class T>
void List<T>::Erase(Node<T>* n)
{
assert(n);
if (n == _head)
{
PopFront();
}
else if (n == _tail)
{
PopBack();
}
else
{
Node<T>* prev = n->_prev;
Node<T>* next = n->_next;
prev->_next = next;
next->_prev = prev;
delete n;
}
}
template<class T>
void List<T>::Reverse()
{
// 没有节点 or 一个节点则直接返回
if (_head == _tail)
{
return;
}
Node<T>* newHead = _head;
Node<T>* newTail = _head;
Node<T>* begin = _head->_next;
while (begin)
{
Node<T>* tmp = begin;
begin = begin->_next;
tmp->_next = newHead;
newHead->_prev = tmp;
newHead = tmp;
}
newTail->_next = NULL;
newHead->_prev = NULL;
_head = newHead;
_tail = newTail;
}
template<class T>
void List<T>::Clear()
{
Node<T>* begin = _head;
while (begin)
{
Node<T>* del = begin;
begin = begin->_next;
delete del;
}
}
template<class T>
void List<T>::Print()
{
Node<T>* begin = _head;
while (begin)
{
cout << begin->_data << "->";
begin = begin->_next;
}
cout << "NULL" << endl;
}
#include <iostream>
using namespace std;
#include "List.hpp"
void Test1()
{
List<int> l;
l.PushBack(1);
l.PushBack(2);
l.PushBack(3);
l.PushBack(4);
l.Print();
l.PopBack();
l.PopBack();
l.PopBack();
l.PopBack();
l.Print();
cout << endl;
}
void Test2()
{
List<int> l;
l.PushFront(1);
l.PushFront(2);
l.PushFront(3);
l.PushFront(4);
l.Print();
l.PopFront();
l.PopFront();
l.PopFront();
l.PopFront();
l.Print();
cout << endl;
}
void Test3()
{
List<int> l;
l.PushFront(1);
l.PushFront(2);
l.PushFront(3);
l.PushFront(4);
l.Print();
Node<int>* ret = l.Find(2);
l.Insert(ret, 0);
l.Print();
l.Erase(ret);
l.Print();
cout << endl;
}
void Test4()
{
List<int> l;
l.PushFront(1);
l.PushFront(2);
l.PushFront(3);
l.PushFront(4);
l.Print();
l.Reverse();
l.Print();
cout << endl;
}
int main()
{
Test1();
Test2();
Test3();
Test4();
return 0;
}