链表操作是最基本的、必须掌握的知识点,最好滚瓜烂熟,透彻理解。工作时间短用的也不够频繁,还是总结一下比较好,以加强巩固。
1. 单链表
结点形式
区分几个概念:
首节点:第一个元素所在节点。
头指针:指向首节点的指针。
头结点:为了操作方便,在第一个节点之前附设的一个结点,此时指向头结点的为头指针。
基本操作:
(1)返回指定元素
status GetElem_L(LinkList L,int i,ElemType &e)
{ //L为带头结点的单链表的头指针
p=L->next; j=1;
while(p&&j<i) {p=p->next; ++j;}
if(!p || j>i) return ERROR;
e=p->data;
return OK;
} //GetElem_L
(2)插入元素
status ListInsert_L(LinkList &L, int i, ElemType &e)
{//带头结点的单链表L中第i个位置之前插入e
p=L; j=0;
while(p&&j<i-1) {p=p->next; ++j}
if(!p || j>i-1) return ERROR;
s=(LinkList)malloc(sizeof(LNode));
s->data=e; s->next=p->next; p->nextt=s;
return OK;
} //ListInsert_L
(3)删除元素
statue ListDelete_L(LinkList &L, int i, ElemType &e)
{ //删除第i个元素,由e返回其值
p=L; j=0;
while(p->next&&j<i-1) {p=p->next; ++j;}
if(!(p->next) || j>i-1) return ERROR;
q=p->next; p->next=q->next;
e=q->data; free(q);
return OK;
} //ListDelete_L
(4)创建链表
void CreateList_L(LinkList &L,int n)
{ //逆位序输入n个元素的值,建立带头结点的单链表
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL; // 建立空表
for(i=n;i>0;--i)
{
p=(LinkList)n=malloc(sizeof(LNode));
scanf(&p->data);
p->next = L->next; L->next=p;
}
}// CreateList_L
2. 双向链表
结点形式
(1)插入元素
status ListInsert_Dul(DulLinkList &L,int i,ElemType e)
{
if(!(p=GetElem_Dull(L,i))) return ERROR;
if(!(s=(DulLinkList)malloc(sizeof(DulNode))))
return ERROR;
s->data=e;
s->prior=p->prior; p->prior->next=s;
s->next=p; p->prior=s;
return OK;
}// ListInsert_Dul
(2)删除元素
status ListDelete_Dul(DulLinkList &L,int i,ElemType &e)
{
if(!(p=GetElem_Dul(L,i))) return ERROR;
e=p->data;
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
return ok;
}// ListDelete_Dul
(3)合并链表
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc)
{
pa=La->next; pb=Lb->next; Lc=pc=La;
while(pa&&pb)
if(pa->data<=pb->data)
{ pc->next=pa; pc=pa; pa=pa->next;}
else { pc->next=pb; pc=pb; pb=pb->next;}
pc->next=pa?pa:pb;
free(Lb); //释放头结点
}// MergeList_L
3. 带头结点的循环链表
尾节点:*R; 头结点:*(R->next) 首节点:*(R->next->next)
int ListLength_cL(LinkList L)
{
p=L; n=0;
while(p->next!=L) {p=p->next; n++;}
return n;
}// ListInsert_cL