例一:求表長
設一個移動工作指針p和一個計數器j,初始時p=L->next,J=0,若p非空,則計數器加1,並將指針下移一個位置,直到達鏈表尾,算法描述如下:
int LinkListLen(LinkList L)
{
//求帶頭結點的單鏈表L的長度
LNode *p
int j=0;
p=L->next;//p指向第一個結點
while(p){j++;p=p->next;}//p指向第j個節點
return j;
}
例二:編寫一個將單循環鏈表逆置的算法
解: 設置一個工作指針p,初始指向單循環鏈表L的第一結點,將L的next域指向L,即建立一個空單循環鏈表,然後採用頭插法將所有結點插入到單循環鏈表L中,算法如下:
int conrrayCirLinkList(CirLinkList &L){//頭插法建立
LNode *p ,*q;
p=->next;
L->next=L;//建立空單循環鏈表
while(p!=L)
{
q=p;
p=p->next;
q->next=L->next;
L->next=q;
}
return OK;
}
例三:一直有兩個帶頭結點的循環單鏈表,設計一個算法,用最快速度將這兩個表合成一個帶頭結點的循環單鏈表。要求時間複雜度O(1),且佔用輔助空間最小。
解: 根據要求,只有設尾指針的單循環鏈表才能實現。算法如下:
void UnionCirLinkList(CirLinkList &Ls,CirLinkList &Lb){
//La和Lb是帶頭結點的單循環鏈表
LNode *q;
q=Lb->next;//q指向Lb的頭結點
Lb->next=La->next;//Lb的後繼結點爲La的頭結點
La->next=q->next;//La的後繼結點爲原Lb的第一個元素結點
delete q;//釋放原Lb的頭結點
}
例四:
將兩個有序表La和Lb歸併成一個有序表,要求不能另設新空間。
解: 算法如下
void mergelist(LinkList &La,LinkList &Lb,LinkList &Lb)
{
LinkList pa,pb,pc;
pa=La->next;pb=Lb->next;
Lc=pc=La;
while(pa&&pb)
{
if(pa->data<=pb->data)
{
pc->next=pa;
pc=pa;
pa=pc->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
if(!pa)pc->next=pb;
if(!pb)pc->next=pa;
delete Lb;
}
例五: 一元稀疏多項式相加。
解: 鏈表的存儲結構如下:
typedef struct
{
float coef;//係數
int expn;//指數
}term,ElemType;
typedef struct Lnode
{
Elemtype data;
struct Lnode *next;
}Lnode,*LinkList
對於兩個一元多項式所有指數相同的項,將對應係數相加,若其和不爲0,則構成“和多項式”中的一項;對兩個一元多項式中指數不同的項,則分別復抄到“和多項式”中。
算法描述如下:
void addlist(LinkList &La,LinkList &Lb)
{
pa=La->next;
pb=Lb->next;
pc=pa;//指向鏈表當前結尾點
while(pa&&pb)
{
if(pa->data.expn<pb->data.expn)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
if(pa->data.expn<pb->data.expn)
{
pc->next=pb;
pc=pb;
pb=pa->next;
}
else
{
sum=pa->data.coef + pb->data.coef;
if(sum==0)
{
p=pa;
pa=pa->next;
delete p;
p=pb;
pb=pb->next;
delete p;
}
else
{
pa->data.coef=sum;
pc->next=pa;
pc=pa;
pa=pa->next;
p=pb;
pb=pb->next;
delete p;
}
}
}
if(pa)pc->next=pa;
if(pb)pc->next=pb;
delete Lb;//釋放Lb頭指針
}
例六: 設L是帶頭結點的頭指針,試編寫算法,按照遞增次序輸出單鏈表各節點的數據元素,並釋放所佔的存儲空間。要求不允許使用數組作爲輔助空間。
解: 應對鏈表進行遍歷,每次遍歷中查找出整個鏈表的最小元素,輸出並釋放頭結點所佔空間。算法如下:
void deleteMin(LinkList &L)
{
LNode *pre,*p,*q;
while(L->next)
{
pre=L;
p=L->next;//p爲工作指針
while(p->next)
if(p->next->data < pre->next->data)
{
pre=p;
p=p->next;
}
else
p=p->next;
printf("%d",pre->next->data);//輸出元素最小結點的數據
q=pre->next;
pre->next=q->next;
delete (q);//刪除元素最小結點
}
delete (L);//釋放頭結點
}
例七: 有一個雙向鏈表從第二個結點到表尾遞增有序。試編寫算法,將第一個結點刪除並插入到適當位置,使整個鏈表遞增有序。
解: 算法如下:
void insertnode(DuLinkLinst &L)
{
DuNode *p,*q,*r;
p=L->next;
L->next=p->next;
p->next->prior=L;
q=L->next;//q爲工作指針
r=L;//r爲q的前驅
while (q&&q->data < p->data)
{
r=q;
q=q->next;
}
if(q)
{
q->prior->next=p;
p->prior=q->prior;
p->next=q;
q->prior=p;
}
else
{//插在尾部
p->next=r->next;
r->next=q;
p->prior=r;
}
}
終於要下雨了,熱成狗了!