3.8.1 双向链表定义
双向链表:在单链表的每个结点中,再设置一个指向其前驱结点的指针域。
双向链表的结构定义如下:
typedef struct DuLNode{
Elemtype data;
struct DuLNode *prior,*next; /*直接前驱结点*/
}DuLNode,*DuLinkList; /*直接后继结点*/
双向链表结构的对称性(设指针p指向某一结点):
3.8.2 双向链表的一些基本操作
双向链表的插入:
void Listlnsert_Dul(DuLinklist &L,int i,ElemType e){
//在带头结点的双向循环链表L中第i个位置之前插入元素e
if(!(p=GetElemP_DuL(L,i)))
return ERROR;
s=(DuLinkList)malloc(sizeof(DuLinkList));//分配空间
s->data=e;
s->prior=p->prior;
p->prior->next=s;
s->next=p;
p->prior=s;
}
双向链表的删除:
void ListDelete_DuL(DuLink &L,int i,ElemType &e){
//删除带头结点的双向循环链表L的第i个元素,并用e返回。
if(!(p=GetElemP_DuL(L,i)))
return ERROR;
e=p->data;
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
}
3.8.2 单链表、循环链表、双向链表的时间效率比较
查找表头结点 (首元结点) | 查找表尾结点 | 查找结点*p的前驱结点 | |
带头结点的单链表 | L->next 时间复杂度O(1) | 从L->next依次向后遍历 时间复杂度O(n) | 通过p->next无法找到其前驱 |
带头结点仅设头指 针L的循环单链表 | L->next 时间复杂度O(1) | 从L->next依次向后遍历 时间复杂度O(n) | 通过p->next可以找到其前驱 时间复杂度O(n) |
带头结点仅设尾指 针R的循环单链表 | R->next 时间复杂度O(1) | R 时间复杂度O(1) | 通过p->next可以找到其前驱 时间复杂度O(n) |
带头结点的双向循 环链表L | L- >next 时间复杂度O(1) | L-> prior 时间复杂度O(1) | p->prior 时间复杂度O(1) |
3.8.3 顺序表和链表的比较