在鏈表這種特殊的數據結構中,鏈表的長短需要根據具體情況來設定,當需要保存數據時向系統申請存儲空間,並將數
據接入鏈表中。對鏈表而言,表中的數據可以依此接到表尾或連結到表頭,也可以視情況插入表中;對不再需要的數據
,將其從表中刪除並釋放其所佔空間,但不能破壞鏈表的結構。這就是下面將介紹的鏈表的插入與刪除。
1. 鏈表的刪除
如創建一個學生學號及姓名的單鏈表,即節點包括學生學號、姓名及指向下一個節點的指針,鏈表按學生的學號排列。
再從鍵盤輸入某一學生姓名,將其從鏈表中刪除。
首先定義鏈表的結構:
從鏈表中刪除一個節點有三種情況,即刪除鏈表頭節點、刪除鏈表的中間節點、刪除鏈表的尾節點。題目給出的是學生
姓名,則應在鏈表中從頭到尾依此查找各節點,並與各節點的學生姓名比較,若相同,則查找成功,否則,找不到節點
。由於刪除的節點可能在鏈表的頭,會對鏈表的頭指針造成丟失,所以定義刪除節點的函數的返回值定義爲
返回結構體類型的指針。
struct node *delet(head,pstr)/*以head爲頭指針,刪除pstr所在節點*/
struct node *head;
char *pstr;
{
struct node*temp,*p;
temp = head; /* 鏈表的頭指針*/
if (head==NULL)/*鏈表爲空*/
printf("\nListis null!\n");
else /*非空表*/
{
temp = head;
while (strcmp(temp->str,pstr)!=0&&temp->next!=NULL)/* 若節點的字符串與輸入字符串不同,並且未到鏈表尾*/
{
p = temp;
temp = tmep->next;/* 跟蹤鏈表的增長,即指針後移*/
}
if(strcmp(temp->str,pstr)==0) /*找到字符串*/
{
if(temp==head) { /* 表頭節點*/
printf("delete string :%s\n",temp->str);
head = head->next;
free(temp);/*釋放被刪節點*/
}
else
{
p->next=temp->next; /*表中節點*/
printf("delete string :%s\n",temp->str);
free(temp);
}
}
else
printf("\nno find string!\n");/*沒找到要刪除的字符串*/
}
return(head);
}
2. 鏈表的插入
首先定義鏈表的結構:
struct
{
int num; /*學生學號* /
char str[20]; /*姓名* /
struct node *next;
} ;
在建立的單鏈表中,插入節點有三種情況,如圖所示;
插入的節點可以在表頭、表中或表尾。假定我們按照以學號爲順序建立鏈表,則插入的節點依次與表中節點相比較,找
到插入位置。由於插入的節點可能在鏈表的頭,會對鏈表的頭指針造成修改,所以定義插入節點的函數的返回值定義爲
返回結構體類型的指針。節點的插入函數如下:
struct node *insert(head,pstr,n) /*插入學號爲n、姓名爲p s t r 的節點*/
struct node *head; /*鏈表的頭指針*/
char *pstr;
int n;
{
struct node *p1,*p2,*p3;
p1=(struct node*)malloc(sizeof(struct node))/*分配一個新節點*/
strcpy(p1->str,pstr); /*寫入節點的姓名字串*/
p1->num = n; /* 學號*/
p2 = head;
if(head==NULL) /* 空表*/
{
head=p1;
p1->next=NULL;/*新節點插入表頭*/
}
else/*非空表*/
{
while(n>p2->num&&p2->next!=NULL)
/*輸入的學號小於節點的學號,並且未到表尾*/
{
p3 = p2;
p2 = p2->next;/* 跟蹤鏈表增長*/
}
if(n<=p2->num) /*找到插入位置*/
if(head==p2) /* 插入位置在表頭*/
{
head = p1;
p1->next = p2;
}
else
{ /*插入位置在表中*/
p3->next = p1;
p1->next = p2;
}
else
{ /*插入位置在表尾*/
p2->next = p1;
p1->next = NULL;
}
}
return(head); /* 返回鏈表的頭指針*/
}
實例:
創建包含學號、姓名節點的單鏈表。其節點數任意個,表以學號爲序,低學號的在前,高學號的在後,以輸入姓名爲空
作結束。在此鏈表中,要求刪除一個給定姓名的節點,並插入一個給定學號和姓名的節點。
# include <stdlib.h>
# include <malloc.h>
struct node /*節點的數據結構*/
{
int num;
char str[20];
struct node *next;
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
main( )
{
/*函數聲明*/
struct node *creat();
struct node *insert();
struct node *delet();
void print( );
struct node *head;
char str[20];
int n;
head=NULL; /*做空表*/
head=creat(head); /*調用函數創建以head 爲頭的鏈表*/
print(head);/*調用函數輸出節點*/
printf("\n input inserted num,name:\n");
gets(str); /*輸入學號*/
n=atoi(str);
gets(str); /*輸入姓名*/
head=insert(head, str, n); /*節點插入鏈表*/
print(head);
printf("\n input deleted name:\n");
gets(str); /*輸入被刪姓名*/
head=delet(head,str); /*用函數刪除節點*/
print(head); /*調用函數輸出節點*/
return;
}
/* * * * * * * * * * * * * * * * * * * * * */
/* * * 創建鏈表* * * * * * * * * * * */
struct node *creat(struct node *head)
{
char temp[30];
struct node *pl,*p2;
pl=p2=(struct node*)malloc(sizeof(struct node));
printf("input num, name: \n");
printf("exit:double times Enter!\n");
gets(temp);
gets(pl->str);
pl->num=atoi(temp);
pl->next = NULL ;
while(strlen(pl->str)>0)
{
if(head==NULL)//if the chain is null
head= pl;//
else
p2->next=pl;//set the p2->next NULL
p2 = pl;//
pl=(struct node*)malloc(sizeof(struct node));
printf ("input num, name: \n");
printf("exit:double times Enter!\n");
gets(temp);
gets(pl->str);
pl->num=atoi(temp);
pl->next= NULL;
}
return head;
}
/* * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * 插入節點* * * * * * * * * */
struct node *insert(head, pstr,n)
struct node *head;
char *pstr;
int n;
{
struct node *pl,*p2,*p3;
pl=(struct node*)malloc(sizeof(struct node));
strcpy (pl->str, pstr);
pl->num = n;
p2 = head;
if(head == NULL)
{
head = pl;
pl->next = NULL;
}
else
{
while (n>p2->num&&p2->next!=NULL)
{
p3 = p2;
p2= p2->next;
}
if (n<=p2->num)
if (head==p2)
{
head = pl;
pl->next = p2;
}
else
{
p3->next = pl;
pl->next= p2;
}
else
{
p2->next= pl;
pl->next = NULL;
}
}
return(head);
}
/* * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * 刪除節點* * * * * * * * * * * * */
struct node *delet (head, pstr)
struct node *head;
char *pstr;
{
struct node *temp,*p;
temp =head;
if (head==NULL)
printf("\nList is null!\n");
else
{
temp = head;
while(strcmp(temp->str,pstr)!= 0 && temp->next!=NULL)
{
p = temp;
temp= temp->next;
}
if(strcmp(temp->str,pstr)== 0)
{
if (temp== head)
{
head = head->next;
free(temp);
}
else
{
p->next =temp->next;
printf("delete string :%s\n",temp->str);
free(temp);
}
}
else
printf("\nno find string!\n");
}
return(head);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * 鏈表各節點的輸出* * * * * * * * * */
void print(struct node *head)
{
struct node *temp;
temp = head;
printf("\n output strings:\n");
while (temp!=NULL)
{
printf("\n%d-----%s\n",temp->num,temp->str);
temp= temp->next;
}
return;
}
運行結果:
root@android-virtual-machine:/uniteq_smb/test# ./test1
input num, name:
exit:double times Enter!
11
aa
input num, name:
exit:double times Enter!
12
bb
input num, name:
exit:double times Enter!
output strings:
11-----aa
12-----bb
input inserted num,name:
13
cc
output strings:
11-----aa
12-----bb
13-----cc
input deleted name:
aa
output strings:
12-----bb
13-----cc