2.2循环链表
比单链表多了个尾指针,指向头结点
2.2.1循环链表的合并
LinkList merge(LinkList LA, LinkList LB) {
p=LA; q=LB;
while(p->next!=LA) p=p->next; /*找到表LA的表尾*/
while(q->next!=LB) q=q->next; //找到表LB的表尾
p->next=LB->next; //表LA的尾指针指向LB首元结点
q->next=LA; //LB尾结点指向LA头结点
free(LB);
return(LA);
}
若想用O(1)的时间复杂度合并两个单链表成为一个循环链表,可采用尾指针
2.3双向链表
每个结点都比单链表多了一个prior域
2.3.1定义
typedef struct DNode {
ElemType data;
struct DNode *prior,*next;
} DNode,*DoubleList;
2.3.2插入
2.3.2.1前插:将结点s插在结点p之前
s->prior=p->prior;
s->next=p;
p->prior->next=s;
p->prior=s;
注意先操作s结点的prior和next域,否则会改变p结点的指向,造成混乱
2.3.2.2后插:将结点s插在结点p之后
s->prior=p;
s->next=p->next;
p->next=s;
s->next->prior=s;
写法不唯一,但要注意某结点指向一旦改变后,后续再利用此结点指向时,避免混乱
int DlinkIns(DoubleList L,int i,ElemType e){
p=L; j=0;
while(p->next!=L&&j<i-1) { p=p->next; j++; }//找到第i-1个结点做插入操作
s=(DNode*)malloc(sizeof(DNode));
if(s){ s->data=e;
s->next=p->next; s->prior=p;
p->next=s; s->next->prior=s; return TRUE; }
else return FALSE;
}
2.3.3删除
删除p结点
p->prior->next=p->next;
p->next->prior=p->prior;
int DlinkDel(DoubleList L,int i,ElemType *e) {
p=L; j=0;
while(p->next!=L&&j<i) { p=p->next; j++; }//找到第i个元素对应的p结点
*e=p->data;
p->prior->next=p->next;
p->next->prior=p->prior;
free(p); return TRUE;
}