双向链表的节点有两个指针域,其一指向前驱,另一个指向后继。
形态:
(1)链表为空时
(2)链表不为空时:
实现:
/******************************************
双向循环链表的实现
by Rowandjj
date:2014.4.1
******************************************/
#include<iostream>
using namespace std;
#define OVERFLOW -1
typedef int ElemType;
/*线性表的双向链表存储结构*/
typedef struct _DULNODE_
{
ElemType data;
struct _DULNODE_ *prior;
struct _DULNODE_ *next;
}DulNode,*DuLinkList,*pDulNode;
/***************操作定义******************/
void InitList(DuLinkList &L);//产生空的双向循环链表
int DestroyList(DuLinkList &L);//销毁双向循环链表
int ClearList(DuLinkList &L);//将表清空
int ListEmpty(DuLinkList L);//判断链表是否为空
int ListLength(DuLinkList L);//返回链表长度
int GetElem(DuLinkList L,int i,ElemType &e);//获取指定位置的元素的值并赋给e
int LocateElem(DuLinkList L,ElemType e,int (*compare)(ElemType,ElemType));//返回L中第1个与e满足关系compare()的数据元素的位序
int PriorElem(DuLinkList L,ElemType cur_e,ElemType &pre_e);//返回元素前驱
int NextElem(DuLinkList L,ElemType cur_e,ElemType &next_e);//返回元素后继
int ListInsert(DuLinkList &L,int i,ElemType e);//插入元素
int ListDelete(DuLinkList &L,int i,ElemType &e);//删除元素,用e返回
void ListTraverse(DuLinkList L,void(*visit)(ElemType));//顺序遍历链表
DuLinkList GetElemP(DuLinkList L,int i);//在双向链表L中返回第i个元素的位置指针
int compare(ElemType e1,ElemType e2);
void visit(ElemType e);
void CreateList(DuLinkList &L,int n);
/***************具体实现*******************/
void InitList(DuLinkList &L)
{
L = (pDulNode)malloc(sizeof(DulNode));
if(!L)
{
exit(OVERFLOW);
}
L->next = L->prior = L;
}
int DestroyList(DuLinkList &L)
{
pDulNode q,p = L->next;
while(p!=L)
{
q = p->next;
free(p);
p = q;
}
free(L);
L = NULL;
return 1;
}
int ClearList(DuLinkList &L)
{
pDulNode q,p = L->next;
while(p != L)
{
q = p->next;
free(p);
p = q;
}
L->next = L->prior = L;
return 1;
}
int ListEmpty(DuLinkList L)
{
return L->next == L && L->prior == L;
}
int ListLength(DuLinkList L)
{
pDulNode p = L->next;
int count = 0;
while(p != L)
{
p = p->next;
count++;
}
return count;
}
int GetElem(DuLinkList L,int i,ElemType &e)
{
pDulNode p = L->next;
int j = 1;
while(j < i && p != L)
{
j++;
p = p->next;
}
if(j>i || p == L)
{
return 0;
}
e = p->data;
return 1;
}
int LocateElem(DuLinkList L,ElemType e,int (*compare)(ElemType,ElemType))
{
pDulNode p = L->next;
int i = 0;
while(p != L)
{
i++;
if(compare(e,p->data))
{
return i;
}
p = p->next;
}
return 0;
}
int compare(ElemType e1,ElemType e2)
{
return e1 == e2;
}
int PriorElem(DuLinkList L,ElemType cur_e,ElemType &pre_e)
{
if(ListEmpty(L))
{
return 0;
}
pDulNode p = L->next->next;
if(p == L)
{
return 0;
}
while(p != L)
{
if(p->data == cur_e)
{
pre_e = p->prior->data;
return 1;
}
p = p->next;
}
return 0;
}
int NextElem(DuLinkList L,ElemType cur_e,ElemType &next_e)
{
if(ListEmpty(L))
{
return 0;
}
pDulNode p = L->next->next;
if(p == L)
{
return 0;
}
while(p != L)
{
if(p->prior->data == cur_e)
{
next_e = p->data;
return 1;
}
p = p->next;
}
return 0;
}
DuLinkList GetElemP(DuLinkList L,int i)
{
int j;
pDulNode p = L;
for( j = 1; j<= i;j++)
{
p = p->next;
}
return p;
}
int ListInsert(DuLinkList &L,int i,ElemType e)
{
if(i < 1 || i > ListLength(L)+1)
{
return 0;
}
pDulNode p = GetElemP(L,i-1);
if(!p)
{
return 0;
}
pDulNode q = (pDulNode)malloc(sizeof(DulNode));
if(!q)
{
return 0;
}
q->data = e;
q->next = p->next;
q->prior = p;
p->next->prior = q;
p->next = q;
return 1;
}
int ListDelete(DuLinkList &L,int i,ElemType &e)
{
if(i<1 || i>ListLength(L))
{
return 0;
}
pDulNode p = GetElemP(L,i);
if(!p)
{
return 0;
}
e = p->data;
p->prior->next = p->next;
p->next->prior = p->prior;
return 1;
}
void ListTraverse(DuLinkList L,void (*visit)(ElemType))
{
pDulNode p = L->next;
while(p != L)
{
visit(p->data);
p = p->next;
}
cout<<endl;
}
void CreateList(DuLinkList &L,int n)
{
if(n <= 0)
{
return;
}
ElemType e;
for(int i = 0; i < n; i++)
{
cin>>e;
pDulNode p = (pDulNode)malloc(sizeof(DulNode));
if(!p)
{
return;
}
p->next = L->next;
p->prior = L;
L->next->prior = p;
L->next = p;
p->data = e;
}
}
void visit(ElemType e)
{
cout<<e<<" ";
}