当单向循环链表的结点中既存在指向后继结点的指针next,又存在指向前驱结点的指针时prev,就构成了双向循环链表。
这样从某个结点出发,既能够方便的找到后继,也能够方便地找到前驱。
还能够方便的在表尾插入数据,因为head->prev就是最后一个结点。
本文用C++的类模板实现了一个双向循环链表的部分功能,
如插入数据、删除数据、得到第i个元素的地址,查找元素x是否存着等
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
template<typename T>class list
{//双向循环链表
struct node
{
T data;
node *prev;
node *next;
};
node *head;//头结点
int length;
public:
void init()
{
head = new node;
head->next = head;
head->prev = head;
length = 0;
}
list()
{
init();
}
int size()
{
return length;
}
void print()
{
node *p;
p = head->next;
while (p != head)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
node* creatNode(T x)
{//为x生成结点,返回结点地址
node *t;
t = new node;
t->data = x;
t->prev = t->next = 0;
return t;
}
void insert(node *p, T x)
{//在指针p所指的结点后面插入x
node *q, *t;
t = creatNode(x);
q = p->next;
if (q != 0)
{
p->next = t; t->prev = p;
t->next = q; q->prev = t;
}
else
{
p->next = t; t->prev = p;
}
length++;
}
void push_front(T x)
{
insert(head, x);
}
void push_back(T x)
{
insert(head->prev, x);
}
node *Address(int i)
{//得到第i个元素结点的地址
if (i<1 || i>length)
return 0;
int j=0;
node *p = head;
while (j < i)
{
p = p->next;
j++;
}
return p;
}
void insert(int i, T x)
{//在链表的第i个数据前面插入x
//即在第i-1个元素后面插入x
node *p;
if (i == 1)
push_front(x);
else if (i == length + 1)
push_back(x);
else
{
p = Address(i - 1);
insert(p, x);
}
}
void erase(int i)
{//删除第i个元素结点
if (i<1 || i>length)
return;
node *p, *q, *t;
t = Address(i);
p = t->prev;
q = t->next;
p->next = q;
q->prev = p;
delete t;
length--;
}
node* find(T x)
{
node *p = head->next;
while (p != head)
{
if (p->data == x)
return p;
p = p->next;
}
return 0;
}
~list()
{
node *p = head->next;
node *q;
while (p != head)
{
q = p->next;
delete p;
p = q;
}
delete head;
head = 0;
length = 0;
}
};
int main()
{
list<int> L;
L.push_front(3);
L.push_front(2);
L.push_front(1);
L.print();
L.push_back(4);
L.push_back(5);
L.push_back(6);
L.print();
cout << L.size() << endl;
cout << (L.Address(6)->data) << endl;
L.insert(1,44);
L.print();
L.insert(3, 55);
L.print();
L.insert(8, 66);
L.print();
cout << "begin to delete:\n";
L.erase(1);
L.print();
L.erase(L.size());
L.print();
L.erase(3);
L.print();
cout << L.find(55)->data << endl;
return 0;
}
C++STL模板库中的list模板就是双向循环链表。