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

C++实现双向链表

2017-03-25 23:52 288 查看
上一篇用C++实现了单链表。今天呢,我们来看看双向链表如何通过C++实现。双向链表也叫双链表,它的的每个数据节点都有两个指针,分别指向直接后继直接前驱。所以从双向链表中的任何一个节点开始,都可以很方便的访问它的前驱节点后继节点





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

struct DListNode   //节点的创建
{
DataType data;
DListNode* next;
DListNode* prev;

DListNode(DataType x)  //节点初始化
:data(x),next(NULL),prev(NULL)
{}

};

class DList
{
typedef DListNode Node;
public:
DList()
:_head(NULL), _tail(NULL)
{}

DList(const DList& l)
:_head(NULL),_tail(NULL)
{
if (l._head == NULL)
{
return;
}
else
{
Node* cur = l._head;
while (cur)
{
PushBack(cur->data);
cur = cur->next;
}
}
}

//DList& operator=(const DList& l)    //传统写法
//{
//  if (this != &l)
//  {
//      _head = NULL;
//      _tail = NULL;
//      Node* cur = l._head;
//      while (cur)
//      {
//          PushBack(cur->data);
//          cur = cur->next;
//      }
//      _tail->next = NULL;
//  }
//  return *this;
//}

//DList& operator=(const DList& l)  //现代写法
//{
//  if (this != &l)
//  {
//      DList tmp(l);
//      swap(_head, tmp._head);
//      swap(_tail, tmp._tail);
//  }
//  return *this;
//}

DList& operator=(const DList l)    // 再优化,传值操作
{
if (this != &l)
{
DList tmp(l);
swap(_head, tmp._head);
swap(_tail, tmp._tail);
}
return *this;
}

~DList()
{
Clear();
}

void PushBack(DataType x)
{
if (_head == NULL)
{
_head = new Node(x);
_tail = _head;
}
else
{
Node* tmp = new Node(x);
_tail->next = tmp;
tmp->prev = _tail;
_tail = _tail->next;
}
return;
}

void PopBack()
{
if (_head == NULL)
{
return;
}
else if (_head == _tail)
{
delete _tail;
_head = NULL;
_tail = NULL;
return;
}
else
{
Node* per = _tail;
_tail = _tail->prev;
delete per;
_tail->next = NULL;
return;
}
}

void PushPront(DataType x)
{
if (_head == NULL)
{
_head = new Node(x);
_tail = _head;
}
else
{
Node* tmp = new Node(x);
tmp->next = _head;
_head->prev = tmp;
_head = _head->prev;
}
return;
}

void PopPront()
{
if (_head == NULL)
{
return;
}
else if (_head == _tail)
{
delete _tail;
_tail = NULL;
_head = NULL;
return;
}
else
{
Node* cur = _head;
_head = _head->next;
delete cur;
_head->prev = NULL;
}
}

void Insert(Node* pos,DataType x)
{
assert(pos);
if (pos == _head)
{
PushPront(x);
}
else if (pos == _tail)
{
PushBack(x);
}
else
{
Node* tmp = new Node(x);
Node* head = pos->prev;
head->next = tmp;
tmp->prev = head;
tmp->next = pos;
pos->prev = tmp;
}
return;
}

Node* Find(DataType x)
{
Node* cur = _head;
while (cur->data != x)
{
cur = cur->next;
}
return cur;
}

void Erase(Node* pos)
{
assert(pos);
if (pos == _head)
{
PopPront();
}
else if (pos == _tail)
{
PopBack();
}
else
{
Node* cur = _head;
while (cur != pos)
{
cur = cur->next;
}
pos->prev->next = pos->next;
pos->next->prev = pos->prev;
delete pos;
}
}

//void Reverse()     //对称位置值交换
//{
//  Node* cur1 = _head;
//  Node* cur2 = _tail;
//  while ((cur1 != cur2)&&(cur1->prev != cur2))
//  {
//      swap(cur1->data, cur2->data);
//      cur1 = cur1->next;
//      cur2 = cur2->prev;
//  }
//  return;
//}

void Reverse()      //通过交换每一个节点上的两个指针来实现逆置
{
Node* cur = _head;
while (cur)
{
Node* next = cur->next;
swap(cur->next, cur->prev);
//cur = cur->prev;
cur = next;
}
swap(_head, _tail);
}

void Clear()
{

while (_head)
{
Node* cur = _head;
_head = _head->next;
delete cur;
}
_head = _tail = NULL;
}

void Display()
{
Node* cur = _head;
while (cur)
{
cout << cur->data << "-";
cur = cur->next;
}
cout << endl;
}
private:
Node* _head;
Node* _tail;
};

void Test1()
{
DList l1;
l1.PushBack(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
l1.Display();
DList l2(l1);
l2.Display();
l1.PopBack();
l1.PopBack();
l1.PopBack();
l1.PopBack();
l1.Display();

}
void Test2()
{
DList l1;
l1.PushPront(1);
l1.PushPront(2);
l1.PushPront(3);
l1.PushPront(4);
l1.Display();
l1.PopPront();
l1.PopPront();
l1.PopPront();
l1.PopPront();
l1.Display();
}

void Test3()
{
DList l1;
l1.PushBack(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
l1.Insert(l1.Find(3), 9);
l1.Display();
l1.Erase(l1.Find(3));
l1.Display();
l1.Reverse();
l1.Display();
DList l2;
l2 = l1;
l2.Display();
}

int main()
{
Test3();
system("pause");
return 0;
}


上一篇我们已经详细讲解了单链表的实现,双向链表与之差不了多少,只是每个节点上多了一个指向直接前驱的指针,所以,这里就不进行详细讲解。多见谅!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 双向链表