上篇的链表时只有一个后继的指针域,这样只能从从左向右进行查找其他结点,如果要查找前驱结点,则只能从表头出发进行查找,效率较低,这篇我们研究一下双向链表。链表的结点有两个指针域,分别指向前驱和后继。
程序实现:(DbLinkList.h)
#ifndef DBLINKLIST_H_
#define DBLINKLIST_H_
#include <iostream>
//结点类
template <typename T>
struct DblNode
{
//数据成员
T data;
DblNode<T> *back;
DblNode<T> *next;
//构造函数
DblNode();
DblNode(T, DblNode<T> *linkback=NULL, DblNode<T> *linknext=NULL);
};
template<typename T>
DblNode<T>::DblNode()
{
back=NULL;
next=NULL;
}
template <typename T>
DblNode<T>::DblNode(T item, DblNode<T> *linkback=NULL, DblNode<T> *linknext=NULL)
{
data=item;
back=linkback;
next=linknext;
}
//简单双向循环链表类
template <typename T>
class SimpleDblLinkList
{
protected:
DblNode<T> *head;//头指针
DblNode<T> *GetElemPtr(int position) const;
void Init();
public:
SimpleDblLinkList();
virtual ~SimpleDblLinkList();
bool IsEmpty();
void Clear();
int Length();
SimpleDblLinkList<T> &DeleteElem(int position, T &e);
SimpleDblLinkList<T> &InsertElem(int position, T e);
SimpleDblLinkList<T> &SetElem(int position, T e);
void GetElem(int position, T &e);
SimpleDblLinkList(const SimpleDblLinkList<T> ©);
SimpleDblLinkList<T> &operator =(const SimpleDblLinkList<T> ©);
};
template <typename T>
DblNode<T> *SimpleDblLinkList<T>::GetElemPtr(int position) const
{
int curPosition=0;
DblNode<T> *tempPtr=head;
while(tempPtr->next!=head && curPosition <position)
{
tempPtr=tempPtr->next;
++curPosition;
}
if(curPosition==position)
{
return tempPtr;
}
else
{
return NULL;
}
}
template <typename T>
void SimpleDblLinkList<T>::Init()
{
head =new DblNode<T>;
head->next=head;
head->back=head;
}
template <typename T>
SimpleDblLinkList<T>::SimpleDblLinkList()
{
Init();
}
template <typename T>
SimpleDblLinkList<T>::~SimpleDblLinkList()
{
Clear();
delete head;
}
template <typename T>
bool SimpleDblLinkList<T>::IsEmpty()
{
//DblNode<T> *tempPtr=head;
if(head==head->next)
{
return true;
}
else
{
return false;
}
}
template <typename T>
void SimpleDblLinkList<T>::Clear()
{
T e;
while(head->next!=head)
{
DeleteElem(1, e);
}
/*delete head;*/
}
template <typename T>
int SimpleDblLinkList<T>::Length()
{
int count=0;
DblNode<T> *tempPtr=head;
while(head!=tempPtr->next)
{
++count;
tempPtr=tempPtr->next;
}
return count;
}
template <typename T>
SimpleDblLinkList<T> &SimpleDblLinkList<T>::DeleteElem(int position, T &e)
{
if(position<1 || position>(Length()+1))
{
std::cout<<"访问元素超出范围!"<<std::endl;
}
else
{
DblNode<T> *tempPtr=GetElemPtr(position);
tempPtr->back->next=tempPtr->next;//修改向右的指针
tempPtr->next->back=tempPtr->back;//修改向左的指针
e=tempPtr->data;
delete tempPtr;
}
return *this;
}
template <typename T>
SimpleDblLinkList<T> &SimpleDblLinkList<T>::InsertElem(int position, T e)
{
if(position<1 || position>(Length()+1))
{
std::cout<<"访问元素超出范围!"<<std::endl;
}
else
{
DblNode<T> *tempPtr=GetElemPtr(position-1);
DblNode<T> *nextPtr=tempPtr->next;
DblNode<T> *newPtr;
newPtr=new DblNode<T>(e, tempPtr,nextPtr);
nextPtr->back=newPtr;
tempPtr->next=newPtr;
//tempPtr->next=newPtr;//修改向右的指针
//tempPtr->back=newPtr;
//newPtr->next=tempPtr;//修改向左的指针
//newPtr->back=tempPtr;
/* newPtr->data=e;*/
/*delete tempPtr;*/
}
return *this;
}
template<typename T>
SimpleDblLinkList<T> &SimpleDblLinkList<T>::SetElem(int position, T e)
{
if(position<1 || position>(Length()+1))
{
std::cout<<"访问元素超出范围!"<<std::endl;
}
else
{
DblNode<T> *tempPtr=GetElemPtr(position);
tempPtr->data=e;
/*delete tempPtr;*/
}
return *this;
}
template<typename T>
void SimpleDblLinkList<T>::GetElem(int position, T &e)
{
if(position<1 || position>(Length()+1))
{
std::cout<<"访问元素超出范围!"<<std::endl;
}
else
{
DblNode<T> *tempPtr=GetElemPtr(position);
e=tempPtr->data;
/*delete tempPtr;*/
}
/*return *this;*/
}
template<typename T>
SimpleDblLinkList<T>::SimpleDblLinkList(const SimpleDblLinkList<T> ©)
{
Init();
int copyLength=copy.Length();
DblNode<T> *tempPtr;
for(int curPosition=1; curPosition<=position; curPosition++)
{
tempPtr=copy.GetElemPtr(curPosition);
tempPtr=tempPtr->next;
}
}
template <typename T>
SimpleDblLinkList<T> &SimpleDblLinkList<T>::operator =(const SimpleDblLinkList<T> ©)
{
if(copy!=this)
{
Init();
int copyLength=copy.Length();
DblNode<T> *tempPtr;
for(int curPosition=1; curPosition<=position; curPosition++)
{
tempPtr=copy.GetElemPtr(curPosition);
tempPtr=tempPtr->next;
}
}
return *this;
}
template <typename T>
std::ostream &operator <<(std::ostream &os, SimpleDblLinkList<T> &DblLinkList)
{
int Len=DblLinkList.Length();
T e;
for(int curPosition=1; curPosition<=Len; curPosition++)
{
DblLinkList.GetElem(curPosition,e);
cout<<e<<" ";
}
return os;
}
#endif
源程序:(DbLinkList.cpp)
// DbLinkList.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include "DbLinkList.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
SimpleDblLinkList<int> DblLinkList;
cout<<"循环链表的长度为:"<<DblLinkList.Length()<<endl;
cout<<"链表是否为空?";
if(DblLinkList.IsEmpty()==1)
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
DblLinkList.InsertElem(1,1);
cout<<"循环链表的长度为:"<<DblLinkList.Length()<<endl;
cout<<"链表是否为空?";
if(DblLinkList.IsEmpty()==1)
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
DblLinkList.InsertElem(1,1).InsertElem(2,2).InsertElem(3,3).InsertElem(4,4).InsertElem(5,5);
cout<<"循环链表的长度为:"<<DblLinkList.Length()<<endl;
cout<<"链表是否为空?";
if(DblLinkList.IsEmpty()==1)
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
int e;
int Length=DblLinkList.Length();
for(int i=1; i<=Length;i++)
{
DblLinkList.GetElem(i,e);
cout<<"链表第二个元素为:"<<e<<endl;
}
cout<<"双向链表为:"<<DblLinkList<<endl;
DblLinkList.SetElem(1,1000);
cout<<"双向链表为:"<<DblLinkList<<endl;
system("pause");
return 0;
}
实验结果: