链表前面我已经写过了,不过写的是单链表,而C++库中的list是双链表,那么,我们就来模拟实现一下双链表,这样对于库中的list也会有更加深刻的了解。
那么首先我们先来了解一下双链表的结构,双链表无非就是比单链表多了一条链,单链表只有一条指向下一个节点的链,而双链表会多一条指向前一个节点的链。说白了就是多了一个指针罢了。
而具体的函数功能还是那些,那么我们就来实现这个链表吧!
#include<iostream>
using namespace std;
#include<assert.h>
#pragma once
typedef int DataType;
struct Node //节点
{
Node(const DataType& data)
: _data(data)
, _pNext(NULL)
, _pPre(NULL)
{}
DataType _data; //值
Node* _pNext; //下一个节点
Node* _pPre; //上一个节点
};
class List
{
public:
List()
: _pHead(NULL)
, _pTail(NULL)
, _size(0)
{}
List(size_t n, const DataType& data = DataType())
{}
List(const List& l)
{
// _CopyList(l._pHead);
}
List& operator=(const List& l)
{
if (this != &l)
{
//_DestroyList();
//_CopyList(l._pHead);
}
return *this;
}
~List()
{
_DestroyList();
}
//尾插
void PushBack(const DataType& data)
{
Node* pNode = new Node(data); //构造一个新的节点
if (NULL == _pHead)
{
_pHead = _pTail = pNode;
}
else
{
_pTail->_pNext = pNode; //先将新节点连接到尾部
pNode->_pPre = _pTail;
_pTail = _pTail->_pNext; //将尾节点向后移一位
}
++_size;
}
//尾删
void PopBack()
{
if (NULL == _pHead)
{
assert(false);
return;
}
else if (_pHead == _pTail)//如果只有一个节点,删除头节点,将两个指针都置空
{
delete _pHead;
_pHead = _pTail = NULL;
}
else
{
_pTail = _pTail->_pPre;//先将尾节点向前移一位
delete _pTail->_pNext;//再将尾节点后面的节点空间释放
_pTail->_pNext = NULL;//最后指针置空
}
--_size;
}
//头插
void PushFront(const DataType& data)
{
Node* pNode = new Node(data);
if (NULL == _pHead)
{
_pHead = _pTail = pNode;
}
else
{
pNode->_pNext = _pHead;
_pHead->_pPre = pNode;
_pHead = pNode;
}
++_size;
}
//头删
void PopFront()
{
if (NULL == _pHead)
{
assert(false);
return;
}
else if (_pHead == _pTail)
{
delete _pHead;
_pHead = NULL;
_pTail = NULL;
}
else
{
_pHead = _pHead->_pNext;
delete _pHead->_pPre;
_pHead->_pPre = NULL;
}
--_size;
}
//插入函数
void Insert(Node* pos, const DataType& data)
{
if (NULL == pos || NULL == _pHead)
return;
if (pos == _pTail)
{
PushBack(data);
}
else
{
Node* pNode = new Node(data);
pNode->_pNext = pos->_pNext;// 1
pos->_pNext->_pPre = pNode;
pos->_pNext = pNode;// 2
pNode->_pPre = pos;
++_size;
}
}
//删除
void Erase(Node* pos)
{
if (NULL == pos || NULL == _pHead)
{
return;
}
else if (pos==_pHead)
{
PopFront();
}
else if (pos == _pTail)
{
PopBack();
}
else
{
pos->_pPre->_pNext = pos->_pNext;
pos->_pNext->_pPre = pos->_pPre;
delete pos;
pos = NULL;
--_size;
}
}
void Assign(size_t n, const DataType data = DataType());
void Clear()
{
_DestroyList();
_size = 0;
}
void _DestroyList()
{
size_t size = _size;
while (size)
{
PopFront();
--size;
}
}
void PrintList()
{
Node* pCur = _pHead;
size_t size = _size; //不要直接使用_size,否则会造成_size,变成很大的数
while (size)
{
cout << pCur->_data <<" ";
pCur = pCur->_pNext;
--size;
}
cout << endl;
}
//access
Node& Front()
{
return *_pHead;
}
const Node& Front()const
{
return *_pHead;
}
Node& Back()
{
return *_pTail;
}
const Node& Back()const
{
return *_pTail;
}
size_t Size()const
{
return _size;
}
bool Empty()const
{
return 0 == _size;
}
private:
Node* _pHead;
Node* _pTail;
size_t _size;
};
void FunTest()
{
List l;
l.PushBack(10);
l.PushBack(20);
l.PushBack(30);
l.PushBack(40);
l.PushBack(666);
l.PrintList();
l.PopBack();
l.PrintList();
l.PushFront(888);
l.PrintList();
l.PopFront();
l.PrintList();
cout <<(l.Back())._data<< endl;
cout << (l.Front())._data << endl;
cout << l.Size() << endl;
l.Clear();
l.PrintList();
}
int main()
{
FunTest();
return 0;
}