双链表的每个数据结点中都有两个指针(前驱指针、后驱指针),分别指向直接后继节点和直接前驱节点。
双向链表中的任意一个结点开始,都可以很方便地访问它的前驱节点点和后继节点。
/*
DLinkedList.h
*/
#pragma once
#include <iostream>
using namespace std;
/*
节点结构体
*/
template <class DataType>
struct Node
{
DataType data;
struct Node* prior;
struct Node* next;
Node() {
this->data = NULL;
this->prior = NULL;
this->next = NULL;
}
Node(DataType data) {
this->data = data;
this->prior = NULL;
this->next = NULL;
}
};
template <class DataType>
class DLinkedList
{
public:
DLinkedList();
~DLinkedList();
// 获取当前顺序表长度
int Length();
// 按值查询(返回位序)
int LocateElement(DataType x);
// 按位查询
DataType ValueOfIndex(int i);
// 尾插法
void TailInsert(DataType data);
// 头插法
void HeadInsert(DataType data);
// 指定位序处插入
bool Insert(DataType data, int i);
// 判断顺序表是否为空
bool IsEmpty();
// 按位删除
bool DeleteByIndex(int i);
// 从头遍历
void PrintFromHead();
// 从尾遍历
void PrintFromTail();
private:
Node<DataType>* head;
Node<DataType>* tail;
int length;
};
/*
DLinkedList.cpp
#include "DLinkedList.h"
*/
template<class DataType>
inline DLinkedList<DataType>::DLinkedList()
{
// 初始化头节点和尾节点
this->head = new Node<DataType>;
this->tail = head;
this->length = 0;
}
template<class DataType>
inline DLinkedList<DataType>::~DLinkedList()
{
// 遍历
Node<DataType>* p = head;
// 临时指针
Node<DataType>* q = new Node<DataType>;
// 依次释放指针
while (p->next)
{
q = p->next;
p->next->prior = NULL;
p->prior = NULL;
delete p;
p = q;
}
p = NULL;
delete q;
head = NULL;
delete p;
delete head;
}
// 链表长度
template<class DataType>
inline int DLinkedList<DataType>::Length()
{
return length;
}
// 按值查找
// 返回第一次出现的位序
template<class DataType>
int DLinkedList<DataType>::LocateElement(DataType x)
{
int i = 1;
// 查找该数据
Node<DataType>* p = head->next;
while (p) {
if (p->data == x) {
return i;
}
i++;
p = p->next;
}
// 如果链表中不含该数据,返回0
return 0;
}
// 按位查找
// 返回指定位序的值
template<class DataType>
DataType DLinkedList<DataType>::ValueOfIndex(int i)
{
// 查找该数据
Node<DataType>* p = head;
while (i-- ) {
p = p->next;
}
DataType data = p->data;
delete p;
return data;
}
// 尾插法
template<class DataType>
inline void DLinkedList<DataType>::TailInsert(DataType data)
{
Node<DataType>* node = new Node<DataType>(data);
tail->next = node;
node->prior = tail;
tail = node;
length++;
}
// 头插法
template<class DataType>
void DLinkedList<DataType>::HeadInsert(DataType data)
{
Node<DataType>* node = new Node<DataType>(data);
head->next->prior = node;
node->next = head->next;
node->prior = head;
head->next = node;
length++;
}
// 指定位序插入数据
template<class DataType>
bool DLinkedList<DataType>::Insert(DataType data, int i)
{
if (i < 1 || i > length + 1)
{
cout << "参数错误" << endl;
}
Node<DataType>* node = new Node<DataType>(data);
Node<DataType>* p = head;
while(i--)
{
p = p->next;
}
// 前驱指针
node->next = p->next;
p->next->prior = node;
node->prior = p;
p->next = node;
// 返回
return false;
}
// 判控
template<class DataType>
bool DLinkedList<DataType>::IsEmpty()
{
return !length;
}
// 按位删除
template<class DataType>
bool DLinkedList<DataType>::DeleteByIndex(int i)
{
return false;
}
// 从头遍历输出
template<class DataType>
void DLinkedList<DataType>::PrintFromHead()
{
Node<DataType>* p = head->next;
while (p)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
return;
}
// 从尾遍历输出
template<class DataType>
void DLinkedList<DataType>::PrintFromTail()
{
Node<DataType>* p = tail;
do
{
cout << p->data << " ";
p = p->prior;
} while (p->prior);
cout << endl;
return;
}