c语言 单链表的插入与删除

来源:互联网 发布:淘宝客都在哪里做推广 编辑:程序博客网 时间:2024/06/05 09:01

在链表这种特殊的数据结构中,链表的长短需要根据具体情况来设定,当需要保存数据时向系统申请存储空间,并将数据接入链表中。对链表而言,表中的数据可以依此接到表尾或连结到表头,也可以视情况插入表中;对不再需要的数据,将其从表中删除并释放其所占空间,但不能破坏链表的结构。这就是下面将介绍的链表的插入与删除。

1. 链表的删除

如创建一个学生学号及姓名的单链表,即节点包括学生学号、姓名及指向下一个节点的指针,链表按学生的学号排列。再从键盘输入某一学生姓名,将其从链表中删除。

首先定义链表的结构:

从链表中删除一个节点有三种情况,即删除链表头节点、删除链表的中间节点、删除链表的尾节点。题目给出的是学生姓名,则应在链表中从头到尾依此查找各节点,并与各节点的学生姓名比较,若相同,则查找成功,否则,找不到节点。由于删除的节点可能在链表的头,会对链表的头指针造成丢失,所以定义删除节点的函数的返回值定义为

返回结构体类型的指针。

[cpp] view plain copy
  1. struct node *delet(head,pstr)/*以head为头指针,删除pstr所在节点*/  
  2. struct node *head;  
  3. char *pstr;  
  4. {  
  5.     struct node*temp,*p;  
  6.     temp  = head;  /* 链表的头指针*/  
  7.     if (head==NULL)/*链表为空*/   
  8.         printf("\nListis null!\n");  
  9.     else /*非空表*/  
  10.     {  
  11.                 temp = head;  
  12.         while (strcmp(temp->str,pstr)!=0&&temp->next!=NULL)/* 若节点的字符串与输入字符串不同,并且未到链表尾*/  
  13.         {  
  14.             p = temp;  
  15.             temp = tmep->next;/* 跟踪链表的增长,即指针后移*/  
  16.         }  
  17.         if(strcmp(temp->str,pstr)==0) /*找到字符串*/  
  18.         {  
  19.         if(temp==head) { /* 表头节点*/  
  20.             printf("delete string :%s\n",temp->str);  
  21.             head = head->next;  
  22.             free(temp);/*释放被删节点*/  
  23.         }  
  24.         else  
  25.         {  
  26.             p->next=temp->next; /*表中节点*/  
  27.             printf("delete string :%s\n",temp->str);  
  28.             free(temp);  
  29.         }  
  30.     }  
  31.     else  
  32.     printf("\nno find string!\n");/*没找到要删除的字符串*/  
  33.     }  
  34.     return(head);  
  35. }  

2. 链表的插入

首先定义链表的结构:

[cpp] view plain copy
  1. struct  
  2. {  
  3. int num; /*学生学号* /  
  4. char str[20]; /*姓名* /  
  5. struct node *next;  
  6. } ;  

在建立的单链表中,插入节点有三种情况,如图所示;



插入的节点可以在表头、表中或表尾。假定我们按照以学号为顺序建立链表,则插入的节点依次与表中节点相比较,找到插入位置。由于插入的节点可能在链表的头,会对链表的头指针造成修改,所以定义插入节点的函数的返回值定义为返回结构体类型的指针。节点的插入函数如下:

[cpp] view plain copy
  1. struct node *insert(head,pstr,n) /*插入学号为n、姓名为p s t r 的节点*/  
  2. struct node *head; /*链表的头指针*/  
  3. char *pstr;   
  4. int n;  
  5. {  
  6.     struct node *p1,*p2,*p3;  
  7.     p1=(struct node*)malloc(sizeof(struct node))/*分配一个新节点*/  
  8.     strcpy(p1->str,pstr); /*写入节点的姓名字串*/  
  9.     p1->num = n; /* 学号*/  
  10.     p2 = head;  
  11.     if(head==NULL) /* 空表*/  
  12.     {  
  13.         head=p1;   
  14.         p1->next=NULL;/*新节点插入表头*/  
  15.     }  
  16.     else/*非空表*/  
  17.     {   
  18.         while(n>p2->num&&p2->next!=NULL)  
  19.         /*输入的学号小于节点的学号,并且未到表尾*/  
  20.         {  
  21.             p3 = p2;  
  22.             p2 = p2->next;/* 跟踪链表增长*/  
  23.         }  
  24.         if(n<=p2->num) /*找到插入位置*/   
  25.         if(head==p2) /* 插入位置在表头*/  
  26.         {  
  27.             head = p1;  
  28.             p1->next = p2;  
  29.         }  
  30.         else  
  31.         { /*插入位置在表中*/  
  32.             p3->next = p1;  
  33.             p1->next = p2;  
  34.         }  
  35.         else  
  36.         { /*插入位置在表尾*/  
  37.             p2->next = p1;  
  38.             p1->next = NULL;  
  39.         }  
  40.     }  
  41.     return(head); /* 返回链表的头指针*/  
  42. }  

实例:

创建包含学号、姓名节点的单链表。其节点数任意个,表以学号为序,低学号的在前,高学号的在后,以输入姓名为空作结束。在此链表中,要求删除一个给定姓名的节点,并插入一个给定学号和姓名的节点。

[cpp] view plain copy
  1. # include <stdlib.h>  
  2. # include <malloc.h>  
  3. struct node /*节点的数据结构*/  
  4. {  
  5.     int num;  
  6.     char str[20];  
  7.     struct node *next;  
  8. };  
  9. /* * * * * * * * * * * * * * * * * * * * * * * * * * * */  
  10. main( )  
  11. {  
  12.     /*函数声明*/  
  13.     struct node *creat();  
  14.     struct node *insert();  
  15.     struct node *delet();  
  16.     void print( );  
  17.     struct node *head;  
  18.     char str[20];  
  19.     int n;  
  20.     head=NULL; /*做空表*/  
  21.     head=creat(head); /*调用函数创建以head 为头的链表*/  
  22.     print(head);/*调用函数输出节点*/  
  23.     printf("\n input inserted num,name:\n");  
  24.     gets(str); /*输入学号*/  
  25.     n=atoi(str);  
  26.     gets(str); /*输入姓名*/  
  27.     head=insert(head, str, n); /*节点插入链表*/  
  28.   
  29.     print(head);  
  30.     printf("\n input deleted name:\n");  
  31.     gets(str); /*输入被删姓名*/  
  32.     head=delet(head,str); /*用函数删除节点*/  
  33.     print(head); /*调用函数输出节点*/  
  34.     return;  
  35. }  
  36. /* * * * * * * * * * * * * * * * * * * * * */  
  37. /* * * 创建链表* * * * * * * * * * * */  
  38. struct node *creat(struct node *head)  
  39. {  
  40.     char temp[30];  
  41.     struct node *pl,*p2;  
  42.     pl=p2=(struct node*)malloc(sizeof(struct node));  
  43.     printf("input num, name: \n");  
  44.     printf("exit:double times Enter!\n");  
  45.     gets(temp);  
  46.     gets(pl->str);  
  47.     pl->num=atoi(temp);  
  48.     pl->next = NULL ;  
  49.     while(strlen(pl->str)>0)  
  50.     {  
  51.         if(head==NULL)//if the chain is null  
  52.              head= pl;//  
  53.         else   
  54.             p2->next=pl;//set the p2->next NULL  
  55.         p2 = pl;//  
  56.     pl=(struct node*)malloc(sizeof(struct node));  
  57.     printf ("input num, name: \n");  
  58.     printf("exit:double times Enter!\n");   
  59.     gets(temp);  
  60.     gets(pl->str);  
  61.     pl->num=atoi(temp);  
  62.     pl->next= NULL;   
  63.     }         
  64.     return head;  
  65. }  
  66. /* * * * * * * * * * * * * * * * * * * */  
  67. /* * * * * * * * * * 插入节点* * * * * * * * * */  
  68. struct node *insert(head, pstr,n)  
  69. struct node *head;  
  70. char *pstr;  
  71. int n;  
  72. {  
  73.     struct node *pl,*p2,*p3;  
  74.     pl=(struct node*)malloc(sizeof(struct node));  
  75.     strcpy (pl->str, pstr);  
  76.     pl->num = n;  
  77.     p2 = head;   
  78.     if(head == NULL)  
  79.   
  80.     {  
  81.         head = pl;   
  82.         pl->next = NULL;  
  83.     }  
  84.     else  
  85.     {  
  86.     while (n>p2->num&&p2->next!=NULL)  
  87.     {  
  88.         p3 = p2;  
  89.         p2= p2->next;  
  90.     }  
  91.     if (n<=p2->num)  
  92.     if (head==p2)  
  93.     {  
  94.         head = pl;  
  95.         pl->next = p2;  
  96.     }  
  97.     else  
  98.     {  
  99.         p3->next = pl;  
  100.         pl->next=  p2;   
  101.     }  
  102.     else  
  103.     {  
  104.         p2->next= pl;  
  105.         pl->next = NULL;  
  106.     }  
  107. }  
  108.     return(head);  
  109. }  
  110. /* * * * * * * * * * * * * * * * * * * * * * * * */  
  111.   
  112.   
  113. /* * * * * 删除节点* * * * * * * * * * * * */  
  114. struct node *delet (head, pstr)  
  115. struct node *head;  
  116. char *pstr;  
  117. {  
  118.     struct node *temp,*p;  
  119.     temp =head;  
  120.     if (head==NULL)  
  121.     printf("\nList is null!\n");  
  122.     else  
  123.     {  
  124.         temp = head;  
  125.         while(strcmp(temp->str,pstr)!= 0 && temp->next!=NULL)  
  126.         {  
  127.             p = temp;  
  128.             temp= temp->next;  
  129.         }  
  130.         if(strcmp(temp->str,pstr)== 0)  
  131.         {  
  132.             if (temp== head)  
  133.             {  
  134.                 head = head->next;  
  135.                 free(temp);  
  136.             }  
  137.             else  
  138.             {  
  139.                 p->next =temp->next;  
  140.                 printf("delete string :%s\n",temp->str);  
  141.                 free(temp);  
  142.             }  
  143.         }  
  144.         else   
  145.             printf("\nno find string!\n");  
  146.     }  
  147.     return(head);  
  148. }  
  149. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */  
  150. /* * * * * * * * * * 链表各节点的输出* * * * * * * * * */    
  151. void print(struct node *head)  
  152. {  
  153. struct node *temp;  
  154. temp = head;  
  155. printf("\n output strings:\n");  
  156. while (temp!=NULL)  
  157. {  
  158. printf("\n%d-----%s\n",temp->num,temp->str);  
  159. temp= temp->next;  
  160. }  
  161. return;  
  162. }   

运行结果:

[cpp] view plain copy
  1. root@android-virtual-machine:/uniteq_smb/test# ./test1  
  2. input num, name:   
  3. exit:double times Enter!  
  4. 11  
  5. aa  
  6. input num, name:   
  7. exit:double times Enter!  
  8. 12  
  9. bb  
  10. input num, name:   
  11. exit:double times Enter!  
  12.   
  13.   
  14.   
  15.  output strings:  
  16.   
  17. 11-----aa  
  18.   
  19. 12-----bb  
  20.   
  21.  input inserted num,name:  
  22. 13  
  23. cc  
  24.   
  25.  output strings:  
  26.   
  27. 11-----aa  
  28.   
  29. 12-----bb  
  30.   
  31. 13-----cc  
  32.   
  33.  input deleted name:  
  34. aa  
  35.   
  36.  output strings:  
  37.   
  38. 12-----bb  
  39.   
  40. 13-----cc  


0 0
原创粉丝点击