您的位置:首页 > 编程语言 > C语言/C++

C++简单实现双链表

2017-10-01 13:20 316 查看
    首先,来了解一下什么是双向链表。官方解释是这样的:双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

来一波图:



   
由上图可以看出:其实双向链表是由很多个节点组成的,而每一个节点又分为三个部分,一个数据域,用于存放数据;两个指针,一个用于指向前一个节点,另一个用于指向后一个节点。而当前边和后边没有节点的时候就指向NULL。

    接下来看具体代码实现:

#include <iostream>
using namespace std;
#include <assert.h>

typedef int DataType;
struct Node
{
Node(const DataType& data)
: _pNext(NULL)
, _pPre(NULL)
, _data(data)
{}

Node* _pNext;
Node* _pPre;
DataType _data;
};

class List
{
public:
List()//构造函数
: _pHead(NULL)
{}

List(DataType* array, size_t size)//构造函数
{
for (size_t i = 0; i < size; ++i)
PushBack(array[i]);
}

~List()//析构函数
{
Node* pTail = _pHead;
while ((_pHead) && (_pHead->_pNext))
{
pTail = _pHead;
_pHead = _pHead->_pNext;
delete pTail;
}
delete _pHead;
}

void PushBack(const DataType data);//后插
void PopBack();//后删
void PushFront(const DataType data);//前插
void PopFront();//前删
Node* Find(const DataType data);
Node* Erase(Node* pos);//删除任意位置节点
Node* Insert(Node* pos, const DataType& data);//任意位置插入
size_t Size();//求节点个数

private:
Node* _pHead;
};

void List::PushBack(const DataType data)//后插
{
Node* pTail
4000
= _pHead;
Node* pNewNode = new Node(data);

if (_pHead == NULL)//空链表
{
_pHead = pNewNode;
pNewNode->_pPre = pTail;
}
else
{
while (pTail->_pNext)
{
pTail = pTail->_pNext;
}

pTail->_pNext = pNewNode;
pNewNode->_pPre = pTail;
}

pNewNode->_data = data;
pNewNode->_pNext = NULL;
}
void List::PopBack()//后删
{
Node* pTail = _pHead;
if (pTail == NULL)
{
return;
}
else
{
while (pTail->_pNext)
{
pTail = pTail->_pNext;
}
pTail->_pPre->_pNext = NULL;//将删除节点前一节点的pNext指针指向NULL
delete pTail;
}
}

前插和后插都差不多,这里就以前插为例做一个详细讲解(前删和后删都特别简单,就不多做讲解了)



具体代码:

void List::PushFront(const DataType data)//前插
{
Node* NewNode = new Node(data);
if (_pHead != NULL)
{
_pHead->_pPre = NewNode;
}
NewNode->_data = data;
NewNode->_pNext = _pHead;
NewNode->_pPre = NULL;
_pHead = NewNode;
}


void List::PopFront()//前删
{
if (_pHead == NULL)
{
return;
}
else
{
Node* del = _pHead;
_pHead = _pHead->_pNext;
_pHead->_pPre = NULL;
delete del;
}
}

Node* List::Find(const DataType data)//查找函数
{
Node* pTail = _pHead;

//空链表
if (pTail == NULL)
{
return NULL;
}

//只有一个节点的情况
else if ((_pHead->_pNext == NULL) && (_pHead->_data == data))
{
return _pHead;
}

//多节点情况
else
{
while (pTail->_pNext)
{
if (data == pTail->_data)
{
return pTail;
}
pTail = pTail->_pNext;
}
}
return NULL;
}


删除任意位置的详解:



具体代码:

Node* List::Erase(Node* pos)//删除任意位置节点
{
if (NULL == pos)
{
return _pHead;
}

if (pos == _pHead)//删除头节点
{
PopFront();
}

else
{
pos->_pPre->_pNext = pos->_pNext;
pos->_pNext->_pPre = pos->_pPre;
delete pos;
}
return _pHead;
}


任意位置插入节点详解:



具体代码:
Node* List::Insert(Node* pos, const DataType& data)//任意位置插入
{
assert(NULL != pos);
Node* NewNode = new Node(data);

if (pos == _pHead)
{
PushFront(data);
return _pHead;
}

else if (NULL == pos->_pNext)
{
PushBack(data);
return _pHead;
}

else
{
NewNode->_pNext = pos;
pos->_pPre->_pNext = NewNode;
NewNode->_pPre = pos->_pPre;
pos->_pPre = NewNode;
NewNode->_data = data;

return _pHead;
}
}


size_t List::Size()//求节点个数
{
if (_pHead == NULL)
{
return 0;
}

else
{
size_t count = 1;
Node* pTail = _pHead;
while (pTail->_pNext)
{
++count;
pTail = pTail->_pNext;
}
return count;
}
}

DataType array[] = { 1, 2, 3, 4, 5, 6 };
List list(array, sizeof(array) / sizeof(array[0]));

void FunTest1()
{
list.PushBack(7);
list.PopBack();

list.PushFront(7);
list.PopFront();
}

void FunTest2()
{
Node* pos = list.Find(2);
list.Erase(pos);

Node* position = list.Find(4);
list.Insert(position, 8);
}

void FunTest3()
{
size_t size = list.Size();
cout << "size=" << size << endl;
}

int main()
{
FunTest1();
FunTest2();
FunTest3();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: