creat函數用於建立一個有n個結點的鏈表,它是一個指針函數,它返回的指針指向stu結構。在creat函數內定義了三個stu結構的指針變量。head為頭指針,pf 為指向兩相鄰結點的前一結點的指針變量。pb為後一結點的指針變量。在for語句內,用malloc函數建立長度與stu長度相等的空間作為一結點,首地址賦予pb。然後輸入結點數據。如果當前結點為第一結點(i==0),則把pb值 (該結點指針)賦予head和pf。如非第一結點,則把pb值賦予pf 所指結點的指針域成員next。而pb所指結點為當前的最後結點,其指針域賦NULL。 再把pb值賦予pf以作下一次循環准備。
creat函數的形參n,表示所建鏈表的結點數,作為for語句的循環次數。圖7.4表示了creat函數的執行過程。
[例7.11]寫一個函數,在鏈表中按學號查找該結點。
TYPE * search (TYPE *head,int n)
{
TYPE *p;
int i;
p=head;
while (p->num!=n && p->next!=NULL)
p=p->next; /* 不是要找的結點後移一步*/
if (p->num==n) return (p);
if (p->num!=n&& p->next==NULL)
printf ("Node %d has not been found!\n",n
}
本函數中使用的符號常量TYPE與例7.10的宏定義相同,等於struct stu。函數有兩個形參,head是指向鏈表的指針變量,n為要查找的學號。進入while語句,逐個檢查結點的num成員是否等於n,如果不等於n且指針域不等於NULL(不是最後結點)則後移一個結點,繼續循環。如找到該結點則返回結點指針。 如循環結束仍未找到該結點則輸出“未找到”的提示信息。
[例7.12]寫一個函數,刪除鏈表中的指定結點。刪除一個結點有兩種情況:
1. 被刪除結點是第一個結點。這種情況只需使head指向第二個結點即可。即head=pb->next。其過程如圖7.5所示。
2. 被刪結點不是第一個結點,這種情況使被刪結點的前一結點指向被刪結點的後一結點即可。即pf->next=pb->next。其過程如圖7.6所示。
函數編程如下:
TYPE * delete(TYPE * head,int num)
{
TYPE *pf,*pb;
if(head==NULL) /*如為空表, 輸出提示信息*/
{ printf("\nempty list!\n");
goto end;}
pb=head;
while (pb->num!=num && pb->next!=NULL)
/*當不是要刪除的結點,而且也不是最後一個結點時,繼續循環*/
{pf=pb;pb=pb->next;}/*pf指向當前結點,pb指向下一結點*/
if(pb->num==num)
{if(pb==head) head=pb->next;
/*如找到被刪結點,且為第一結點,則使head指向第二個結點,
否則使pf所指結點的指針指向下一結點*/
else pf->next=pb->next;
free(pb);
printf("The node is deleted\n");}
else
printf("The node not been foud!\n");
end:
return head;
}
函數有兩個形參,head為指向鏈表第一結點的指針變量,num刪結點的學號。 首先判斷鏈表是否為空,為空則不可能有被刪結點。若不為空,則使pb指針指向鏈表的第一個結點。進入while語句後逐個查找被刪結點。找到被刪結點之後再看是否為第一結點,若是則使head指向第二結點(即把第一結點從鏈中刪去),否則使被刪結點的前一結點(pf所指)指向被刪結點的後一結點(被刪結點的指針域所指)。如若循環結束未找到要刪的結點, 則輸出“末找到”的提示信息。最後返回head值。
[例7.13]寫一個函數,在鏈表中指定位置插入一個結點。在一個鏈表的指定位置插入結點, 要求鏈表本身必須是已按某種規律排好序的。例如,在學生數據鏈表中, 要求學號順序插入一個結點。設被插結點的指針為pi。 可在三種不同情況下插入。
1. 原表是空表,只需使head指向被插結點即可。見圖7.7(a)
2. 被插結點值最小,應插入第一結點之前。這種情況下使head指向被插結點,被插結點的指針域指向原來的第一結點則可。即:pi->next=pb;
head=pi; 見圖7.7(b)
3. 在其它位置插入,見圖7.7(c)。這種情況下,使插入位置的前一結點的指針域指向被插結點,使被插結點的指針域指向插入位置的後一結點。即為:pi->next=pb;pf->next=pi;
4. 在表末插入,見圖7.7(d)。這種情況下使原表末結點指針域指向被插結點,被插結點指針域置為NULL。即:
pb->next=pi;
pi->next=NULL; TYPE * insert(TYPE * head,TYPE *pi)
{
TYPE *pf,*pb;
pb=head;
if(head==NULL) /*空表插入*/
(head=pi;
pi->next=NULL;}
else
{
while((pi->num>pb->num)&&(pb->next!=NULL))
{pf=pb;
pb=pb->next; }/*找插入位置*/
if(pi->num<=pb->num)
{if(head==pb)head=pi;/*在第一結點之前插入*/
else pf->next=pi;/*在其它位置插入*/
pi->next=pb; }
else
{pb->next=pi;
pi->next=NULL;} /*在表末插入*/
}
return head;}
本函數有兩個形參均為指針變量,head指向鏈表,pi 指向被插結點。函數中首先判斷鏈表是否為空,為空則使head指向被插結點。表若不空,則用while語句循環查找插入位置。找到之後再判斷是否在第一結點之前插入,若是則使head 指向被插結點被插結點指針域指向原第一結點,否則在其它位置插入, 若插入的結點大於表中所有結點,則在表末插入。本函數返回一個指針, 是鏈表的頭指針。 當插入的位置在第一個結點之前時, 插入的新結點成為鏈表的第一個結點,因此head的值也有了改變, 故需要把這個指針返回主調函數。