一.引入
在单链表的每个结点中再设置一个指向其前驱结点的指针域,这样就形成了双链表。其中,data 为数据域,存放数据元素;prior 为前驱指针域,存放该结点的前驱结点的地址;next 为后继指针域,存放该结点的后继结点的地址。
二.算法设计
DoubLinkedList.h
#ifndef SRC_DOUBLINKEDLIST_H_
#define SRC_DOUBLINKEDLIST_H_
template <class T>
struct Node{
T data;
Node<T> *prior;
Node<T> *next;
};
template <class T>
class DoubLinkedList {
public:
DoubLinkedList();
DoubLinkedList(T array[],int length);
virtual ~DoubLinkedList();
int getLength();
void getAll();
T getByIndex(int index);
void getByValue(T value);
void insert(int index,T value);//把指针移到插入点的后面
void add(T value);//在尾部添加元素
void removeByIndex(int index);
void removeByValue(T value);
void updateByIndex(int index,T value);
void updateByValue(T oldValue,T newValue);
private:
Node<T> *first;//头结点,prior存储的是第一个节点的地址,next存储的是最后一个节点的地址
Node<T> *sign;//记号指针,用于运行某些方法时移动
int length;
bool checkIndex(int index);//检查角标是否符合要求
void moveSign(int index);//移动记号指针
void resetSign();//重置记号指针,将其指向头结点
};
#endif
三.详细设计(C++)
DoubLinkedList.cpp
#include "DoubLinkedList.h"
#include <iostream>
using namespace std;
template <class T>
bool DoubLinkedList<T>::checkIndex(int index){
if(index < 0){
cout<<"角标不能小于0!"<<endl;
return false;
}else if(index >= length){
cout<<"角标越界,当前长度为:"<<length<<"!"<<endl;
return false;
}
return true;
}
template <class T>
void DoubLinkedList<T>::moveSign(int index){
if(index >= length/2){
sign = first->next;
for(int i = length-1;i > index;i--){
sign = sign->prior;
}
}else{
sign = first->prior;
for(int i = 0;i < index;i++){
sign = sign->next;
}
}
}
template <class T>
void DoubLinkedList<T>::resetSign(){
sign = first;
}
template <class T>
DoubLinkedList<T>::DoubLinkedList(){
first = new Node<T>;
first->prior = first;
first->next = first;
length = 0;
sign = first;
}
template <class T>
DoubLinkedList<T>::DoubLinkedList(T array[],int length){
first = new Node<T>;
for(int i = 0;i < length;i++){
if(i == 0){
Node<T> *s = new Node<T>;
s->prior = s;
s->data = array[i];
s->next = s;
first->prior = s;
first->next = s;
}else{
Node<T> *s = new Node<T>;
s->prior = first->next;
s->data = array[i];
s->next = first->prior;
first->prior->prior = s;
first->next->next = s;
first->next = s;
}
}
this->length = length;
sign = first;
}
template <class T>
DoubLinkedList<T>::~DoubLinkedList(){
Node<T> *removeNode = first->prior;
while(removeNode != first->next){
removeNode = removeNode->next;
removeByIndex(0);
}
delete removeNode;
delete first;
}
template <class T>
int DoubLinkedList<T>::getLength(){
return length;
}
template <class T>
void DoubLinkedList<T>::getAll(){
Node<T> *p = first->prior;
int index = 0;
while(p != first->next){
if(index == 0){
cout<<"["<<p->data<<",";
}else{
cout<<p->data<<",";
}
index++;
p = p->next;
}
cout<<p->data<<"]"<<endl;
}
template <class T>
T DoubLinkedList<T>::getByIndex(int index){
if(!checkIndex(index)){
return -1;
}
moveSign(index);
T data = sign->data;
resetSign();
return data;
}
template <class T>
void DoubLinkedList<T>::getByValue(T value){
Node<T> *p = first->prior;
bool flag = false;
int index = 0;
while(p != first->next){
if(p->data == value){
cout<<"arr["<<index<<"]="<<p->data<<" ";
flag = true;
}
p = p->next;
index++;
}
if(p->data == value){
cout<<"arr["<<index<<"]="<<p->data<<endl;
flag = true;
}
if(!flag){
cout<<"没有此值!"<<endl;
}
}
template <class T>
void DoubLinkedList<T>::insert(int index,T value){
if(!checkIndex(index)){
return;
}
moveSign(index);
Node<T> *insertNode = new Node<T>;
insertNode->prior = sign->prior;
insertNode->data = value;
insertNode->next = sign;
sign->prior->next = insertNode;
sign->prior = insertNode;
if(first->prior == insertNode->next && first->next == insertNode->prior){
first->prior = insertNode;
}
resetSign();
length++;
}
template <class T>
void DoubLinkedList<T>::add(T value){
Node<T> *p = first->prior;
Node<T> *insertNode = new Node<T>;
insertNode->prior = p->prior;
insertNode->data = value;
insertNode->next = p;
p->prior->next = insertNode;
p->prior = insertNode;
first->next = insertNode;
length++;
}
template <class T>
void DoubLinkedList<T>::removeByIndex(int index){
if(!checkIndex(index)){
return;
}
moveSign(index);
if(sign == first->prior){
first->prior = sign->next;
}else if(sign == first->next){
first->next = sign->prior;
}
sign->prior->next = sign->next;
sign->next->prior = sign->prior;
Node<T> *removeNode = sign;
delete removeNode;
length--;
resetSign();
}
template <class T>
void DoubLinkedList<T>::removeByValue(T value){
Node<T> *p = first->prior;
bool flag = false;
int index = 0;
while(p != first->next){
if(p->data == value){
removeByIndex(index);
flag = true;
p = p->next;
continue;
}
p = p->next;
index++;
}
if(p->data == value){
removeByIndex(index);
flag = true;
}
if(!flag){
cout<<"没有此值!"<<endl;
}
}
template <class T>
void DoubLinkedList<T>::updateByIndex(int index,T value){
moveSign(index);
sign->data = value;
resetSign();
}
template <class T>
void DoubLinkedList<T>::updateByValue(T oldValue,T newValue){
Node<T> *p = first->prior;
bool flag = false;
while(p != first->next){
if(p->data == oldValue){
p->data = newValue;
flag = true;
}
p = p->next;
}
if(p->data == oldValue){
p->data = newValue;
flag = true;
}
if(!flag){
cout<<"没有此值!"<<endl;
}
}
四.测试
TestDoubLinkedList.cpp
#include "DoubLinkedList.h"
#include "DoubLinkedList.cpp"
#include <iostream>
using namespace std;
int main(int argc, char **argv) {
int arr[] = {1,2,3,4,5,4,3,2,1};
cout<<"创建对象"<<endl;
DoubLinkedList<int> doubLinkedList(arr,9);
cout<<"对象长度:"<<doubLinkedList.getLength()<<endl;
cout<<"遍历对象:";
doubLinkedList.getAll();
cout<<endl;
cout<<"获取角标为6的元素:"<<doubLinkedList.getByIndex(6)<<endl;
cout<<endl;
cout<<"获取值为3的元素的角标:";
doubLinkedList.getByValue(3);
cout<<endl<<endl;
cout<<"在角标为3的位置插入6:"<<endl;
doubLinkedList.insert(3,6);
cout<<"对象长度:"<<doubLinkedList.getLength()<<endl;
cout<<"遍历对象:";
doubLinkedList.getAll();
cout<<endl;
cout<<"移除角标为3的元素:"<<endl;
doubLinkedList.removeByIndex(3);
cout<<"对象长度:"<<doubLinkedList.getLength()<<endl;
cout<<"遍历对象:";
doubLinkedList.getAll();
cout<<endl;
cout<<"移除值为2的元素:"<<endl;
doubLinkedList.removeByValue(2);
cout<<"对象长度:"<<doubLinkedList.getLength()<<endl;
cout<<"遍历对象:";
doubLinkedList.getAll();
cout<<endl;
cout<<"把角标为5的元素的值修改为0:"<<endl;
doubLinkedList.updateByIndex(5,0);
cout<<"对象长度:"<<doubLinkedList.getLength()<<endl;
cout<<"遍历对象:";
doubLinkedList.getAll();
cout<<endl;
cout<<"把值为4的元素的值修改为8:"<<endl;
doubLinkedList.updateByValue(4,8);
cout<<"对象长度:"<<doubLinkedList.getLength()<<endl;
cout<<"遍历对象:";
doubLinkedList.getAll();
cout<<endl;
cout<<"销毁数组";
doubLinkedList.~DoubLinkedList();
cout<<endl;
return 0;
}
五.运行结果