一、概念
1.在双链表中的每个结点应有两个链接指针:
lLink -> 指向前驱结点 (前驱指针或者左链指针)
rLink->指向后继结点(后驱指针或者右链指针)
2.双链表常采用带附加头结点的循环链表方式:
first:头指针,不存放数据,或者存放特殊要求的数据。它的lLink指向双链表的尾结点(最后一个结点),
它的rLink指向双链表的首结点(第一个有效结点)。链表的首结点的左链指针lLink和尾结点的右链指针
rLink都指向附加头结点。
二、实现程序
1.DblList.h
#ifndef DblList_h
#define DblList_h
#include <iostream>
using namespace std;
template <class T>
struct DblNode { // 链表结点定义
T data;
DblNode<T> *lLink, *rLink; // 链表前驱(左链)和后继(右链)指针
DblNode(DblNode<T> *left = NULL, DblNode<T> *right = NULL):lLink(left), rLink(right){} // 构造函数
DblNode(T value, DblNode<T> *left = NULL, DblNode<T> *right = NULL):data(value), lLink(left), rLink(right){} // 构造函数
};
template <class T>
class DblList { // 双链表(双向循环链表)
public:
DblList(); // 构造函数:建立附加头结点
~DblList(); // 析构函数:释放所有存储
void createDblList(); // 创建双向链表
int Length()const; // 计算双链表的长度
bool isEmpty(); // 判双链表空否
DblNode<T> *getHead()const; // 取附加头结点
void setHead(DblNode<T> *ptr); // 设置附加头结点地址
DblNode<T> *Search(const T x); // 在链表中沿后继方向寻找等于给定值x的结点
DblNode<T> *Locate(int i, int d); // 在链表中定位第i个结点,d=0按前驱方向,否则按后继方向
bool Insert(int i, const T x, int d); // 在第i个结点后插入x,d=0按前驱方向,否则按后继方向
bool Remove(int i, T &x, int d); // 删除第i个结点,x带回删除其值,d=0按前驱方向,否则按后继方向
void Output(); // 输出双链表中的数据
private:
DblNode<T> *first; // 附加头结点
};
template <class T>
DblList<T>::DblList() {
// 构造函数&#x