単方向循環リンクリストのノードに、後続ノードの隣のポインターと先行ノード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テンプレートライブラリのリストテンプレートは、双方向の循環リンクリストです。