博客介绍了C语言,以及C++的单向链表。那么我们今天介绍的双向链表,顾名思义,就是数据本身具备了左边和右边的双向指针。双向链表相比较单向链表,主要有下面几个特点:
(1)在数据结构中具有双向指针
(2)插入数据的时候需要考虑前后的方向的操作
(3)同样,删除数据的是有也需要考虑前后方向的操作
那么,一个非循环的双向链表操作应该是怎么样的呢?我们可以自己尝试一下:
源代码:
#include <iostream>
using namespace std;
typedef int DataType;
class LinkNode
{
friend class List;
public:
LinkNode(const DataType& x)
:_data(x)
,_next(NULL)
,_prev(NULL)
{}
~LinkNode()
{
}
protected:
DataType _data; // 数据
private:
LinkNode* _prev; // 前驱
LinkNode* _next; // 后继
};
class List
{
public:
List()
:_head(NULL)
,_tail(NULL)
{}
~List()
{}
List(const List& l)
{}
List& operator=(const List& l);
public:
void Print()
{
LinkNode *begin=_head;
while (begin)
{
cout<<begin->_data<<"->";
begin=begin->_next;
}
cout<<"NULL"<<endl;
}
void PushBack(const DataType& x)
{
// 1.空链表
// 2.一个或以上节点
if(_head == NULL)
{
_head=new LinkNode(x);
_tail=_head;
}
else
{
_tail->_next=new LinkNode(x);
_tail->_next->_prev=_tail;
_tail=_tail->_next;
}
}
void PopBack()
{
// 1.空链表
// 2.一个节点
// 3.两个及以上节点
if (_head ==NULL)
{
return ;
}
if (_head == _tail)
{
delete _head;
_head = NULL;
_tail = NULL;
}
else
{
LinkNode* del=_tail;
_tail=_tail->_prev;
_tail->_next=NULL;
//_tail->_prev=_tail->_prev; 此句功能包含在_tail=_tail->_prev;中!!
delete del;
/*tail=_tail->_prev;
delete _tail->_next;
_tail->_next=NULL;*/
}
}
void PushFront(const DataType& x)
{
//1.空链表
//2.非空链表
if(_head == NULL)
{
_head=new LinkNode(x);
_tail=_head;
}
else
{
LinkNode *tmp = new LinkNode(x);
tmp->_next=_head;
_head->_prev=tmp;
tmp->_prev = NULL;
_head=tmp;
}
}
void PopFront()
{
// 1.空链表
// 2.一个节点
// 3.两个及以上节点
if (_head == NULL)
{
return ;
}
if (_head == _tail)
{
delete _head;
_head = NULL;
_tail = NULL;
}
if(_head != _tail) //链表清空之后的判断,否则出现内存访问冲突
{
LinkNode *del =(_head);
_head=_head->_next;
_head->_prev=NULL;
delete del;
}
}
//插入
void Insert(LinkNode* pos, const DataType& x)
{
// 1.空链表
// 2.尾部插入
// 3.中间插入
if (_head == NULL)
{
_head=new LinkNode(x);
_tail=_head;
}
if(pos == _tail)
{
PushBack(x);
}
else
{
LinkNode *tmp=new LinkNode(x);
pos->_prev->_next=tmp;
pos->_next->_prev=tmp;
tmp->_prev=pos->_prev;
tmp->_next=pos->_next;
}
}
//查找
LinkNode* Find(const DataType& x)
{
if (_head == NULL)
{
return NULL;
}
LinkNode* begin = _head;
while(begin != NULL)
{
if(begin->_data == x)
{
return begin;
}
else
{
begin = begin->_next ;
}
}
return NULL;
cout<<"没有找到该节点"<<endl;
}
//删除
void Erase(LinkNode* del)
{
//1.空链表
if(_head == NULL)
{
return ;
}
else
{
//2.一个节点且是删除节点
if ((_head == _tail) && (_head == del))
{
delete _head;
_head=NULL;
_tail=NULL;
}
else
{//3.多个节点
//del为头
if (_head == del)
{
PopFront();
/*_head=_head->_next;
_head->_prev=NULL;
delete _head->_prev;*/
}
else
{
//del在尾
if(del == _tail)
{
PopBack();
/*del->_prev->_next=NULL;
_tail=del->_prev;
delete del;*/
}
//del在中
else
{
del->_prev->_next=del->_next;
del->_next->_prev=del->_prev;
delete del;
}
}
}
}
}
void remove(DataType * x)
{
LinkNode *ret=Find(*x);
Erase(ret);
}
//逆置
void Reverse()
{
LinkNode* tmp1 = _head;
LinkNode* tmp2 = _tail;
while(tmp1 != tmp2 && tmp2->_next != tmp1)
{
DataType a = tmp1->_data ;
tmp1->_data = tmp2->_data ;
tmp2->_data = a;
tmp1 = tmp1->_next ;
tmp2 = tmp2->_prev ;
}
}
private:
LinkNode* _head;
LinkNode* _tail;
};
void Test1()
{
List l1;
l1.PushBack(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
l1.Print();
LinkNode* ret = l1.Find(4);
//cout<<"ret:"<<ret->_data<<endl; //测试失败“LinkNode::_data”: 无法访问 protected 成员(在“LinkNode”类中声明)
//l1.PopBack();
//l1.PopBack();
//l1.PopBack();
//l1.PopBack();
//l1.PopBack();
//l1.Insert(s,3);
//l1.PopFront();
//l1.PopFront();
//l1.PopFront();
//l1.PopFront();
//l1.PopFront();
/*l1.PushFront(0);
l1.Print();*/
//l1.Erase(ret);
//l1.Reverse();
/*DataType x=3;
l1.remove(&x);*/
l1.Print();
}
void Test2()
{
List l1;
l1.PushFront(1);
l1.PushFront(2);
l1.PushFront(3);
l1.PushFront(4);
l1.Print();
l1.PopFront();
l1.PopFront();
l1.PopFront();
l1.PopFront();
l1.PopFront();
l1.Print();
}
int main()
{
Test1();
//Test2();
getchar();
return 0;
}