單鏈表的插入與刪除

在鏈表這種特殊的數據結構中,鏈表的長短需要根據具體情況來設定,當需要保存數據時向系統申請存儲空間,並將數

據接入鏈表中。對鏈表而言,表中的數據可以依此接到表尾或連結到表頭,也可以視情況插入表中;對不再需要的數據

,將其從表中刪除並釋放其所佔空間,但不能破壞鏈表的結構。這就是下面將介紹的鏈表的插入與刪除。


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

發佈了95 篇原創文章 · 獲贊 20 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章