双链表(Double Linked List)
双向链表定义
双(向)链表中有两条方向不同的链,即每个结点中除next域存放后继结点地址外,还增加一个指向其直接前驱的指针域prior。
双链表示意图
- 双链表由头指针head惟一确定的。
- 带头结点的双链表的某些运算变得方便。
- 将头结点和尾结点链接起来,为双(向)循环链表。
双向链表的结点结构和类型定义
①结点结构(见上图a)②类型定义
typedef struct DuLNode
{
ElemType data;
struct DuLNode *prior, *next;
}DuLNode, *DuLinkList;
双向链表的前插和删除本结点操作
由于双链表的对称性,在双链表能能方便地完成各种插入、删除操作。
双链表的前插操作
void ListInsert_DuL (DuLinkList p, ElemType x)
{//在带头结点的双链表中,将值为x的新结点插入*p之前,设p≠NULL
DuLinkList s = malloc(sizeof(DListNode)); //为新结点分配内存
s->data=x; //将新结点的数据存入新的区域
s->prior=p->prior; //将新结点链接到其前驱
s->next=p; //将新结点链接到其后继
p->prior->next=s; //将新结点的前驱和新结点链接
p->prior=s; //将新结点的后继和新结点链接
}
双链表上删除结点*p自身的操作
void ListDelete_DuL( DuLinkList p )
{//在带头结点的双链表中,删除结点*p,设*p为非终端结点
p->prior->next=p->next; //将要删除的结点的前驱链接到删除结点的后继
p->next->prior=p->prior; //将要删除的结点的后继链接到删除结点的前驱
free(p); //释放结点指针
}
注意:
与单链表上的插入和删除操作不同的是,在双链表中插入和删除必须同时修改两个方向上的指针。
上述两个算法的时间复杂度均为O(1)。