相比于单链表,除了指向下一个节点的next指针,双向链表在每个节点中,还设置了一个指向前驱节点的prev指针。
双链表示意图
优点:有了向前指向的指针,双向链表的反向查找操作无疑优于单链表,求得了以空间换时间的效果。
缺点:插入或删除节点操作比单链表复杂,需要维护两个指针变量。
双向链表插入结点过程:
双向链表删除结点过程:
完整代码:
#include<iostream>
using namespace std;
typedef int DataType;//双向链表
struct ListNode//节点结构体
{
ListNode* _prev;
ListNode* _next;
DataType _data;
ListNode(DataType x)
:_prev(NULL)
,_next(NULL)
,_data(x)
{}
};
class List
{
typedef ListNode Node;//节点重命名
public:
List()
:_head(NULL)
,_tail(NULL)
{}
List(const List& l)
:_head(NULL)
,_tail(NULL)
{
Node* cur = l._head;
while(cur)
{
PushBack(cur->_data);
cur = cur->_next;
}
}
List &operator=(List l)
{
swap(_head,l._head);//深拷贝的现代写法(借助中间变量交换指针)
swap(_tail,l._tail);
}
void Clear()
{
Node* cur = _head;
while(cur)
{
Node* next = cur->_next;
delete cur;
cur = next;
}
_head = _tail = NULL;
}
~List()
{
Clear();
}
void PushBack(DataType x)
{
if(_tail == NULL )
{
_head = _tail = new Node(x);
}
else
{
Node* tmp = new Node(x);
_tail->_next = tmp;
tmp->_prev = _tail;
_tail = tmp;
}
}
void PopBack()
{
if(_head == NULL)
{
return;
}
else if(_head->_next == NULL)
{
delete _head;
_head = _tail = NULL;
}
else
{
Node* prev = _tail->_prev;
prev->_next = NULL;
delete _tail;
prev = _tail;
}
}
void PushFront(DataType x)
{
Insert(_head,x);
}
void PopFront()
{
if(_head == NULL)
{
return;
}
else if(_head->_next == NULL)
{
delete _head;
_head = _tail = NULL;
}
else
{
Node* tmp = _head;
_head =_head->_next;
delete tmp;
_head->_prev = NULL;
}
}
void Insert(Node* pos, DataType x)
{
Node* tmp = new Node(x);
if(_head == pos)
{
if(_head == NULL)
{
_head = _tail = tmp;
}
else
{
tmp->_next = _head;
(_head->_prev) = tmp;
_head = tmp;
}
}
else
{
Node* prev = pos->_prev;
prev->_next = tmp;
tmp->_prev = prev;
tmp->_next = pos;
pos->_prev = tmp;
}
}
void Erase(Node* pos) //删除pos
{
if((pos == 0) || (pos->_prev == NULL))
{
PopFront();
}
else if(pos->_next == NULL)
{
PopBack();
}
else
{
Node* prev = pos->_prev;
Node* next = pos->_next;
prev->_next = next;
next->_prev = prev;
delete pos;
}
}
Node* Find(DataType x)
{
Node* cur = _head;
while(cur)
{
if(cur->_data == x)
{
return cur;
}
cur = cur->_next;
}
return NULL;
}
void Print()
{
Node* cur = _head;
while(cur)
{
cout<<cur->_data<<" ";
cur = cur->_next;
}
}
void Reverse()
{
Node* cur = _head;
while(cur)
{
swap(cur->_next,cur->_prev);
cur = cur->_prev;
}
swap(_head,_tail);
}
private:
Node* _head;
Node* _tail;
};
//void test1()
//{
// List l1;
// l1.PushBack(1);
// l1.PushBack(2);
// l1.PushBack(3);
// l1.PushBack(4);
// l1.PushBack(5);
// l1.Print();
// printf("\n");
// l1.PushBack(6);
// printf("尾插:");
// l1.Print();
// printf("\n");
// l1.PopBack();
// printf("尾删:");
// l1.Print();
// printf("\n");
// l1.PushFront(0);
// printf("头插:");
// l1.Print();
// printf("\n");
// l1.PopFront();
// printf("头删:");
// l1.Print();
//}
void test2()
{
List l1;
l1.PushBack(1);
l1.PushBack(3);
l1.PushBack(4);
l1.PushBack(2);
l1.PushBack(5);
l1.Print();
printf("\n");
l1.Insert(l1.Find(2),8);
printf("在2前面插入8:");
l1.Print();
printf("\n");
l1.Erase(l1.Find(3));
printf("删除3:");
l1.Print();
printf("\n");
l1.Reverse();
printf("翻转链表:");
l1.Print();
}
int main()
{
//test1();
test2();
return 0;
}
test1 结果:
test2 结果: