双向列表
双向链表是每个结点除后继指针外还有一个前驱指针。和单链表类同,双向链表也有带头结点结构和不带头结点结构两种,带头结点的双向链表更为常用;另外,双向链表也可以有循环和非循环两种结构,循环结构的双向链表更为常用。
双向链表相当于两个单向循环链表,双链表节点结构如下图示:
双链表节点比单链表多一个前驱指针域。
如下图是带头结点的双向循环链表的图示结构。双向循环链表的next和prior各自构成自己的单向循环链表:
在双向链表中,有如下关系:设对象引用p表示双向链表中的第i个结点,则p->next表示第i+1个结点,p->next->prior仍表示第i个结点,即p->next->prior == p;同样地,p->prior表示第i-1个结点,p->prior->next仍表示第i个结点,即p->prior->next == p。下图是双向链表上述关系的图示:
双向循环链表的插入过程:
下图中的指针p表示要插入结点的位置,s表示要插入的结点,①、②、③、④表示实现插入过程的步骤:
s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;
循环双向链表的删除过程:
下图中的指针p表示要插入结点的位置,①、②表示实现删除过程的步骤:
p->prior->next = p->next;
p->next->prior = p->prior;
下面用C++ 代码实现双向链表:
头文件:
#include<iostream>
using namespace std;
#ifndef TT_DU_LINK_LIST
#define TT_DU_LINK_LIST
#define TT_OK 1
#define TT_ERROR 0
namespace tt
{
class DuLinkList
{
public:
typedef int ElemType;
typedef void Status;
public:
struct DulNode
{
ElemType m_data; //数据域
DulNode *m_prior; //指向前驱结点的指针
DulNode *m_next; //指向后继结点的指针
};
public:
DuLinkList();
~DuLinkList();
ElemType insertAt(ElemType i, ElemType elem);
ElemType removeAt(ElemType i, ElemType &elemOut);
ElemType getAt(ElemType i, ElemType &elemOut);
ElemType getIndexElemAt(ElemType &i, ElemType elemOut);//查找与elem相等的元素,返回第一个与elem相等元素在链表中的序号
ElemType getLength()const;
ElemType isEmpty()const;
ElemType destroy();
ElemType clear();
Status show();
Status traverseBack();
ElemType priorElemAt(ElemType cur_e, ElemType &pri_e);//若cur_e是链表的数据元素,且不是第一个,则用pre_e返回它的前驱
ElemType nextElemAt(ElemType cur_e, ElemType &Nex_e); //若cur_e是链表的数据元素,且不是最后一个,则用next_e返回它的后继,
Status createTail(ElemType *datas, ElemType length);//创建长度为length的链表,数据通过数组指定,这里采用尾插法
private:
DulNode *m_heap;
};
inline DuLinkList::ElemType DuLinkList::isEmpty()const
{
return ((m_heap->m_next == m_heap) && (m_heap->m_prior == m_heap));
}
}
#endif //TT_DU_LINK_LIST
源文件:
#include"MyDuLinkList.h"
namespace tt
{
DuLinkList::DuLinkList()
{
m_heap = new DulNode;
if (!m_heap)
{
cout << "错误,内存分配失败!" << endl;
system("pause");
exit(0);
}
/*m_heap->m_next = m_heap;
m_heap->m_prior = m_heap;*/
m_heap->m_next = m_heap->m_prior = m_heap;
cout << "\n********************双向的循环链表初始化成功!************************" << endl;
}
DuLinkList::~DuLinkList()
{
this->destroy();
}
DuLinkList::Status DuLinkList::createTail(ElemType *datas, ElemType length)//创建长度为length的链表,数据通过数组指定,这里采用尾插法
{
DulNode *m = m_heap;
for (int i = 0; i < length; ++i)
{
DulNode *p = new DulNode;
if (!p)
{
cout << "错误,无法分配内存,创建链表失败!" << endl;
system("pause");
exit(0);
}
p->m_data = datas[i]