参考资源:
【1】http://zh.wikipedia.org/wiki/双向链表
【2】《百度文库》
【3】《算法导论》
【4】http://blog.sina.com.cn/s/blog_77795cad01011ud1.html
注:
本文部分文字学习并copy自网络.
如果侵犯了您的版权,请联系本人tangyibiao520@163.com,本人将及时编辑掉!
一,双向链表的基本操作
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
//定位指定的位置,返回该位置上的结点指针
DoubleListNode<DataType>* Locate(int nPos);
//摧毁双链表
void DestroyDoubleLinkList();
//获得双链表长度
int Length();
//插入节点
bool InsertNode(DataType item,int nPos);
//打印双链表
void PrintList();
//删除结点
bool RemoveNode(int nPos);
//获得指定位置的数据
DataType getData(int nPos);
//判断空否
bool IsEmpty();
//链表逆置
void Reverse();
二,双向链表的代码实现
(1)DoubleLinkList.h代码如下:
<pre name="code" class="html">#include "stdafx.h"
#include "iostream"
using namespace std;
template<class DataType>class DoubleLinkList;
template <class DataType>
class DoubleListNode
{
public:
DoubleListNode()
{
pre=NULL;
next=NULL;
}
DoubleListNode(DataType item)
{
nValue=item;
pre=NULL;
next=NULL;
}
~DoubleListNode()
{
pre=NULL;
next=NULL;
}
private:
friend class DoubleLinkList<DataType>;
DataType nValue;
DoubleListNode<DataType> *pre;
DoubleListNode<DataType> *next;
};
template<class DataType>
class DoubleLinkList
{
public:
DoubleLinkList(int size)
{
head =new DoubleListNode<DataType>();
maxSize=size;
nLength=0;
}
~DoubleLinkList()
{
DestroyDoubleLinkList();
//delete head;
}
//定位指定的位置,返回该位置上的结点指针
DoubleListNode<DataType>* Locate(int nPos);
//摧毁双链表
void DestroyDoubleLinkList();
//获得双链表长度
int Length();
//插入节点
bool InsertNode(DataType item,int nPos);
//打印双链表
void PrintList();
//删除结点
bool RemoveNode(int nPos);
//获得指定位置的数据
DataType getData(int nPos);
//判断空否
bool IsEmpty();
//链表逆置
void Reverse();
private:
DoubleListNode<DataType> *head;
int maxSize;
int nLength;
};
template<class DataType>
DoubleListNode<DataType>* DoubleLinkList<DataType>::Locate(int nPos)
{
DoubleListNode<DataType> *p = head;//head和p指向共同的内容,头结点无数据
if (nPos < 0)
{
cerr<<"位置参数有错误"<<endl;
return NULL;
}
int i = 0;
while (p != NULL && i < nPos)
{
p = p->next;
i++;
}
return p;
}
template<class DataType>
bool DoubleLinkList<DataType>::InsertNode(DataType item,int nPos)
{
if (Length() >= maxSize)
{
cout<<"错误:双链表已满"<<endl;
exit(1);
}
if (nPos < 0)
{
cerr<<"插入位置无效"<<endl;
return false;
}
DoubleListNode<DataType> *newNode=new DoubleListNode<DataType>(item);
if (newNode==NULL)
{
cerr<<"内存分配错误"<<endl;
exit(1);
}
DoubleListNode<DataType> *p=Locate(nPos);
if (p->next==NULL)//如果当前节点是末尾节点的话
{
newNode->pre=p;
p->next=newNode;
}else
{
newNode->pre=p;
newNode->next=p->next;
p->next=newNode;
p->next->pre=newNode;
}
nLength++;
return true;
}
template<class DataType>
void DoubleLinkList<DataType>::DestroyDoubleLinkList()
{
DoubleListNode<DataType> *pMove=head->next;
DoubleListNode<DataType> *pDel;
while (pMove!=NULL)
{
pDel=pMove;
pMove=pMove->next;
delete pDel;
}
head->next=NULL;//这句话必须有,不然有错误
}
template<class DataType>
int DoubleLinkList<DataType>::Length()
{
return nLength;
}
template<class DataType>
void DoubleLinkList<DataType>::PrintList()
{
int count = 0;
DoubleListNode<DataType> *p = head;
while (NULL != p->next)
{
p = p->next;
cout << p->nValue << " ";
if (++count % 15 == 0) //每隔十个元素,换行打印
cout << endl;
}
}
template<class DataType>
bool DoubleLinkList<DataType>::RemoveNode(int nPos)
{
if ((nPos+1)>Length())
{
cerr<<"位置参数错误"<<endl;
exit(1);
}
DoubleListNode<DataType> *p=Locate(nPos);
DoubleListNode<DataType> *del=p->next;
if (del->next==NULL)
{
p->next=NULL;
delete del;
nLength--;
return true;
}
else
{
p->next=del->next;
del->next->pre=p;
delete del;
nLength--;
return true;
}
}
template<class DataType>
DataType DoubleLinkList<DataType>::getData(int nPos)
{
if ((nPos+1)>Length())
{
cerr<<"位置参数错误"<<endl;
exit(1);
}
DoubleListNode<DataType> *p=Locate(nPos);
return p->next->nValue;
}
template<class DataType>
bool DoubleLinkList<DataType>::IsEmpty()
{
if (Length()==0)
{
return true;
}else
{
return false;
}
}
template<class DataType>
void DoubleLinkList<DataType>::Reverse()
{
for (int i=1;i<=Length()/2;i++)
{
DoubleListNode<DataType> *p=Locate(i);
DoubleListNode<DataType> *q=Locate(nLength-i);
DataType temp;
temp=p->nValue;
p->nValue=q->next->nValue;
q->next->nValue=temp;
}
}
(2)主测试函数
</pre><pre name="code" class="html">// ConsoleAppDoubleLinkeList.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "DoubleLinkList.h"
#include "iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
DoubleLinkList<char> S(10);
//插入节点的测试
char A='A';
char B='B';
char C='C';
char D='D';
S.InsertNode(A,0);
S.InsertNode(B,1);
S.InsertNode(C,2);
S.InsertNode(D,1);
S.InsertNode(++D,3);
S.PrintList();
cout<<endl;
cout<<"链表的逆序:"<<endl;
S.Reverse();
S.PrintList();
cout<<endl;
cout<<"当前双链表节点数:"<<S.Length()<<endl;
cout<<"删除指定位置为3的节点(位置均从0开始算)"<<endl;
S.RemoveNode(3);
S.PrintList();
cout<<endl;
cout<<"当前双链表节点数:"<<S.Length()<<endl;
cout<<"获得指定位置2的数据:"<<endl;
cout<<S.getData(2)<<endl;
S.DestroyDoubleLinkList();
cout<<"链表已经摧毁"<<endl;
system("pause");
return 0;
}
(3)测试结果