对于双链表,采用类似于单链表的类型定义,其DLinkList类型的定义如下:
typedef struct DNode //声明双链表节点类型
{ ElemType data;
struct DNode *prior; //指向前驱节点
struct DNode *next; //指向后继节点
} DLinkList;
1.建立双联表
1)头插法
void CreateListF(DLinkList *&L,ElemType a[],int n)
//头插法建立双链表:由含有n个元素的数组a创建带头节点的双链表L
{ DLinkList *s; int i;
L=(DLinkList *)malloc(sizeof(DLinkList));//创建头节点
L->prior=L->next=NULL; //前后指针域置为NULL
for (i=0;i<n;i++) //循环建立数据节点
{ s=(DLinkList *)malloc(sizeof(DLinkList));
s->data=a[i]; //创建数据节点*s
s->next=L->next; //将*s插入到头节点之后
if (L->next!=NULL) //若L存在数据节点,修改前驱指针
L->next->prior=s;
L->next=s;
s->prior=L;
}
}
2)尾插法
void CreateListR(DLinkList *&L,ElemType a[],int n)
//尾插法建立双链表:由含有n个元素的数组a创建带头节点的双链表L
{ DLinkList *s,*r;
int i;
L=(DLinkList *)malloc(sizeof(DLinkList));//创建头节点
r=L; //r始终指向尾节点,开始时指向头节点
for (i=0;i<n;i++) //循环建立数据节点
{ s=(DLinkList *)malloc(sizeof(DLinkList));
s->data=a[i]; //创建数据节点*s
r->next=s;s->prior=r; //将*s插入*r之后
r=s; //r指向尾节点
}
r->next=NULL; //尾节点next域置为NULL
}
2.插入节点
int ListInsert(DLinkList *&L,int i,ElemType e)
{ int j=0;
DLinkList *p=L,*s; //p指向头节点,j设置为0
while (j<i-1 && p!=NULL) //查找第i-1个节点
{ j++;
p=p->next;
}
if (p==NULL) //未找到第i-1个节点,返回false
return -1;
else //找到第i-1个节点*p,在其后插入新节点*s
{ s=(DLinkList *)malloc(sizeof(DLinkList));
s->data=e; //创建新节点*s
s->next=p->next; //在*p之后插入*s节点
if (p->next!=NULL)//若存在后继节点,修改其前驱指针
p->next->prior=s;
s->prior=p;
p->next=s;
return 1;
}
}
3.删除节点
int ListDelete(DLinkList *&L,int i,ElemType &e)
{ int j=0; DLinkList *p=L,*q; //p指向头节点,j设置为0
while (j<i-1 && p!=NULL) //查找第i-1个节点
{ j++;
p=p->next;
}
if (p==NULL) //未找到第i-1个节点
return -1;
else //找到第i-1个节点*p
{ q=p->next; //q指向第i个节点
if (q==NULL) //当不存在第i个节点时返回false
return false;
e=q->data;
p->next=q->next; //从单链表中删除*q节点
if (p->next!=NULL) //修改其前驱指针
p->next->prior=p;
free(q); //释放*q节点
return 1;
}
}
二、循环链表
循环链表是另一种形式的链式存储结构。它的特点是表中最后一个节点的指针域不再是空,而是指向表头节点,整个链表形成一个环。由此从表中任一节点出发均可找到链表中其他节点。
例1,编写出判断带头节点的双向循环链表L是否对称相等的算法。
解:p从左向右扫描L,q从右向左扫描L,若对应数据节点的data域不相等,则退出循环,否则继续比较,直到p与q相等或p的下一个节点为*q为止。
int Equeal(DLinkList *L)
{ int same=1;
DLinkList *p=L->next; //p指向第一个数据节点
DLinkList *q=L->prior; //q指向最后数据节点
while (same==1)
if (p->data!=q->data)
same=0;
else
{
if (p==q) break; //数据节点为奇数的情况
q=q->prior;
if (p==q) break; //数据节点为偶数的情况
p=p->next;
}
return same;
}