一、循环链表:
非空表:
空表:
- 1. 循环链表的特点:最后一个结点的指针域指向头结点,整个链表形成一个环。
- 2.与单链表的差别仅在于链表遍历时,判别当前指针p是否指向表尾结点的终止条件不同:
- 单链表为:p!=NULL或 p->next!= NULL
- 循环链表为:p! = L 或 p->next != L
3.某些情况下,设立尾指针而不设头指针,可使一些操作简化。如将两个线性表合成一个表时,主要语句:
p=B->next->next;
B->next=A->next;
A->next=p;
二、双向链表:
单链表中,查找直接后继结点的执行时间为O(1),而查找直接前驱的执行时间为O(n),为此,产生了双向链表。
①双向链表的存储结构:
//-----双向链表的存储结构-----
typedef struct DuLNode
{
Elemtype date; //数据域
struct DuLNode *prior; //直接前驱
struct DuLNode *next; //直接后继
} DuLNode,*DuLinkList;
②双向链表的插入:
Status ListInsert_DuL(DuLinkList &L,int i,ElemType e)
{//在带头结点的双向链表L中第i个位置之前插入元素e
if(!(p=GetElem_DuL(L,i))) //在L中确定第i个元素的位置指针p
{
return ERROR; //p为NULL时,第i个元素不存在
}
s=new DuLNode; //生成新结点*s
s->date=e; //将结点*s数据域置为e
s->prior=p->prior; //①将结点*s插入L中
s->prior->next=s; //②
s->next=p; //③
p->prior=s; //④
return OK;
}
③双向链表的删除:
Status ListDelete_DuL(DuLinkList &L,int i)
{//删除带头结点的双向链表L中的第i个元素
if(!(p=GetElem_DuL(L,i))) //在L中确定第i个元素的位置指针p
{
return ERROR; //p为NULL时,第i个元素不存在
}
p->prior->next=p->next; //修改被删结点的前驱结点的后继指针 ①
p->next->prior=p->prior; //修改被删结点的后继结点的前驱指针②
delete p; //释放被删结点的空间
return OK;
}