鱼C论坛

 找回密码
 立即注册
查看: 1561|回复: 9

[已解决]C语言链表删除问题求解!

[复制链接]
发表于 2019-9-22 13:04:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
void shanchu(stu *p)
{
        int i;
        printf("请输入删除学生的学号\n");
        scanf("%d",&i);       
        stu * temp =p;
        p=p->pnext;

        while (p != NULL)
        {
                if(p->num==i)
                {
                        temp->pnext= p->pnext;
                        free(p);
                        p=temp->pnext;//上面的P已经被free掉了,再赋值是不是需要重新定义类型??
                }
                temp=temp->pnext;
                p=p->pnext;
        }

p已经被free相当于p的函数已经释放,下面这一步是不是有问题
最佳答案
2019-9-22 23:30:08
本帖最后由 jackz007 于 2019-9-23 00:17 编辑
seglex 发表于 2019-9-22 17:46
这一段中我输入三个数,分别是11 22 22
得到的结果并不是我想象的那样,只删除第一个值,后面的值并没有 ...


      这是我系统地为你修改的代码,新增加了几个函数,你测试一下,看看能否解决你的问题。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. typedef struct student {
  5.         int num                        ;
  6.         char name[20]                  ;
  7.         struct student * pnext         ;
  8. } stu                                  ;

  9. int strip(char * s)
  10. {
  11.         int b , k , m                                                                               ;
  12.         m = strlen(s)                                                                               ;
  13.         while(m > 0 && (s[m - 1] == 0x07 || s[m - 1] == 0x0a || s[m - 1] == 0x0d || s[m - 1] == 0x20)) {
  14.                 s[m - 1] = 0x00                                                                     ;
  15.                 m --                                                                                ;
  16.         }
  17.         if(m > 0) {
  18.                 b = 0                                                                               ;
  19.                 while(b < m && (s[b] == 0x07 || s[b] == 0x0a || s[b] == 0x0d || s[b] == 0x20)) b ++ ;
  20.                 if(b > 0 && b < m) {
  21.                         for(k = b ; k < m ; k ++) s[k - b] = s[k]                                   ;
  22.                         s[m - b] = 0x00                                                             ;
  23.                         m -= b                                                                      ;
  24.                 }
  25.         }
  26.         return m                                                                                    ;
  27. }

  28. int getnum(int * num)
  29. {
  30.         int m , ret                                                ;
  31.         char s[260]                                                ;
  32.         ret = 0                                                    ;
  33.         * num = ret                                                ;
  34.         for(;;) {
  35.                 printf("输入学号 : ")                              ;
  36.                 fgets(s , 256 , stdin)                             ;
  37.                 if(strip(s)) {
  38.                         if(sscanf(s , "%d" , & m) == 1) {
  39.                                 ret = m                            ;
  40.                                 * num = ret                        ;
  41.                                 break                              ;
  42.                         } else {
  43.                                 fprintf(stderr , "输入错误!\n\n") ;
  44.                         }
  45.                 } else {
  46.                         break                                      ;
  47.                 }
  48.         }
  49.         return ret                                                 ;
  50. }

  51. char * getname(char * name)
  52. {
  53.         char s[260] , * ret                                        ;
  54.         name[0] = '\0'                                             ;
  55.         ret = name                                                 ;
  56.         printf("输入姓名 : ")                                      ;
  57.         fgets(s , 256 , stdin)                                     ;
  58.         if(strip(s)) strcpy(name , s)                              ;
  59.         return ret                                                 ;
  60. }

  61. stu * findnode(int num , stu * p)
  62. {
  63.         stu * ret                      ;
  64.         ret = NULL                     ;
  65.         while(p) {
  66.                 if(p -> num == num) {
  67.                         ret = p        ;
  68.                         break          ;
  69.                 } else {
  70.                         p = p -> pnext ;
  71.                 }
  72.         }
  73.         return ret                     ;
  74. }

  75. stu * addnode(stu * p)
  76. {
  77.         int num                                                                  ;
  78.         stu * h , * q                                                            ;
  79.         char name[20]                                                            ;
  80.         bool f                                                                   ;
  81.         f = true                                                                 ;
  82.         h = p                                                                    ;
  83.         printf("\n")                                                             ;
  84.         printf("*** 录入学员信息 ***\n")                                         ;
  85.         for(; f ;) {
  86.                 p = h                                                            ;
  87.                 printf("\n")                                                     ;
  88.                 if(getnum(& num)) {
  89.                         if(! findnode(num , p)) {
  90.                                 if(strlen(getname(name))) {
  91.                                         q = (stu *) malloc(sizeof(stu))          ;
  92.                                         q -> num = num                           ;
  93.                                         strcpy(q -> name , name)                 ;
  94.                                         q -> pnext = NULL                        ;
  95.                                         if(p) {
  96.                                                 while(p -> pnext) p = p -> pnext ;
  97.                                                 p -> pnext = q                   ;
  98.                                         } else {
  99.                                                 p = q                            ;
  100.                                                 h = p                            ;
  101.                                         }                                       
  102.                                 } else {
  103.                                         f = false                                ;
  104.                                 }
  105.                         } else {
  106.                                 fprintf(stderr , "错误:节点已经存在!\n\n")     ;
  107.                         }
  108.                 } else {
  109.                         f = false                                                ;
  110.                 }
  111.         }
  112.         return h                                                                 ;
  113. }

  114. stu * delnode(stu * p)
  115. {
  116.         int num                                                                                               ;
  117.         stu * h , * q                                                                                         ;
  118.         bool f                                                                                                ;
  119.         f = true                                                                                              ;
  120.         printf("\n")                                                                                          ;
  121.         printf("*** 删除学员信息 ***\n")                                                                      ;
  122.         h = p                                                                                                 ;
  123.         if(p) {
  124.                 for(; f ;) {
  125.                         if(h) {
  126.                                 p = h                                                                         ;
  127.                                 printf("\n")                                                                  ;
  128.                                 if(getnum(& num)) {
  129.                                         if((q = findnode(num , p))) {
  130.                                                 while(p != q && p -> pnext && p -> pnext != q) p = p -> pnext ;
  131.                                                 if(p == q || p -> pnext == q) {
  132.                                                         if(p == q) h = p -> pnext                             ;
  133.                                                         else p -> pnext = q -> pnext                          ;
  134.                                                         free(q)                                               ;
  135.                                                 }
  136.                                         } else {
  137.                                                 fprintf(stderr , "错误:节点未找到!\n\n")                    ;
  138.                                         }
  139.                                 } else {
  140.                                         f = false                                                             ;
  141.                                 }
  142.                         } else {
  143.                                 printf("\n")                                                                  ;
  144.                                 printf("链表节点已经全部删除!\n\n")                                          ;
  145.                                 f = false                                                                     ;
  146.                         }
  147.                 }
  148.         } else {
  149.                 fprintf(stderr , "错误:链表为空!\n\n")                                                      ;
  150.         }
  151.         return h                                                                                              ;
  152. }                    

  153. void print(stu * p)
  154. {
  155.         printf("\n")                                              ;
  156.         printf("*** 显示学员信息 ***\n")                          ;
  157.         if(p) {
  158.                 while(p) {
  159.                         printf("%d\t%s\n" , p -> num , p -> name) ;
  160.                         p = p -> pnext                            ;
  161.                 }
  162.         } else {
  163.                 fprintf(stderr , "错误:链表为空!\n\n")          ;
  164.         }
  165. }

  166. int main(void)
  167. {
  168.         stu * p        ;
  169.         p = NULL       ;
  170.         p = addnode(p) ;
  171.         print(p)       ;
  172.         p = delnode(p) ;
  173.         print(p)       ;
  174. }
复制代码

   
      这个代码花了比较大的力气在键盘输入检测方面,任何时候,如果从键盘获取的参数是空回车,则随时结束输入。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-9-22 14:46:25 | 显示全部楼层
free掉的是p中的内容。p本身还是存在的。p就是一个地址的代号。这个是不会删掉的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-9-22 15:39:58 From FishC Mobile | 显示全部楼层
本帖最后由 jackz007 于 2019-9-22 15:49 编辑

        p 只是一个指针,free(p) 所释放的只是 p 所指向的一片内存区域,这片区域,之前是用 p = (stu *)malloc(sizeof(stu)) 从系统中分配得到的。执行完 free(p) ,作为指针本身,p 仍然是存在和可以继续使用的一个 stu * 型的指针。
        p 被释放后,在被重新指向其它节点之前,不可以被继续作为一个 stu 型的节点来使用和访问。
        如果想创建一个新节点,可以使用 malloc() 先分配内存:
p = (stu *)malloc(sizeof(stu))
        然后,就可以通过指针 p 来把数据保存在新节点里面了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-22 16:58:44 | 显示全部楼层
本帖最后由 seglex 于 2019-9-22 17:01 编辑
jackz007 发表于 2019-9-22 15:39
p 只是一个指针,free(p) 所释放的只是 p 所指向的一片内存区域,这片区域,之前是用 p = (stu *)m ...


我试了加了p=(stu *)malloc(sizeof (stu));得出的结果是一样的。
还想请问一下,我发图片回复,您帮我看看

                               
登录/注册后可看大图


                               
登录/注册后可看大图
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-9-22 17:18:59 From FishC Mobile | 显示全部楼层
seglex 发表于 2019-9-22 16:58
我试了加了p=(stu *)malloc(sizeof (stu));得出的结果是一样的。
还想请问一下,我发图片回复,您帮我 ...

      楼主,贴代码文本要比贴图片简单容易的多,找到文本输入区上方的快捷工具栏,按下标有 "<>" 的按钮,把代码文本贴到新弹出的代码框里就得了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-22 17:22:26 | 显示全部楼层
jackz007 发表于 2019-9-22 17:18
楼主,贴代码文本要比贴图片简单容易的多,找到文本输入区上方的快捷工具栏,按下标有 "" 的按钮, ...

好的,您看看
  1. # include <stdio.h>
  2. # include <stdlib.h>
  3. typedef struct student
  4. {
  5.         int num;
  6.         char name[20];
  7.         struct student *pnext;
  8. }stu;


  9. //添加一个新节点
  10. void addnode (stu *p)
  11. {
  12.         int n;
  13.         printf("input\n");
  14.         scanf("%d",&n);
  15.         for(int i=0;i<n;i++)
  16.         {
  17.         stu* pnew;
  18.         pnew =(stu*)malloc(sizeof(stu));
  19.         printf("请输入学员的信息\n");
  20.         printf("姓名");
  21.         scanf("%s",pnew->name);
  22.         printf("学号");
  23.         scanf("%d",&pnew->num);
  24.         p->pnext = pnew;
  25.         p=p->pnext;
  26.         }
  27. }
  28. void print(stu *q)
  29. {
  30.         q=q->pnext;
  31.         printf("\n==================\n");
  32.         while(q!= NULL)
  33.         {
  34.                 printf("%d\t%s\n",q->num,q->name);
  35.                 q=q->pnext;
  36.         }

  37. }
  38. void shanchu(stu *p)
  39. {
  40.         int i;
  41.         printf("请输入删除学生的学号\n");
  42.         scanf("%d",&i);       
  43.         stu * temp =p;//p(头地址)的值赋值给临时变量temp
  44.         p=p->pnext;//首地址第一个有效数字地址赋值给p

  45.         while (p != NULL)
  46.         {
  47.                 if(p->num==i)
  48.                 {
  49.                         temp->pnext= p->pnext;
  50.                         free(p);//释放当前结构体下的p
  51.                         p=(stu *)malloc(sizeof (stu));
  52.                         p =temp->pnext;//指向下一个结构体的p
  53.                         printf("指针的值:%d",p->num);

  54.                 }
  55.                 temp=temp->pnext;// 头地址自增
  56.                 p=p->pnext;//首地址自增 ,
  57.         }
  58.        

  59. int main()
  60. {
  61.         stu *p;
  62.         p =(stu *)malloc(sizeof(stu));
  63.         p->pnext ;
  64.         addnode(p);
  65.         print(p);
  66.         shanchu(p);
  67.         print(p);
  68.         return 0;
  69.        
  70. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-9-22 17:36:36 From FishC Mobile | 显示全部楼层
本帖最后由 jackz007 于 2019-9-22 17:58 编辑
  1. stu * shanchu(stu *p)
  2. {
  3.         stu * q , temp       ;
  4.         int i;
  5.         q = NULL ;
  6.         printf("请输入删除学生的学号\n");
  7.         scanf("%d",&i);
  8.         if (p -> num == i) {
  9.                 q = p ;
  10.                 p = p -> pnext ;
  11.         } else {
  12.                 while (p -> pnext != NULL) {
  13.                         if(p -> pnext -> num == i) {
  14.                                 q = p -> pnext ;
  15.                                 p -> pnext = p -> pnext -> pnext
  16.                                 break ;
  17.                         }
  18.                         p = p -> pnext ;
  19.                 }
  20.         }
  21.         if(q) {
  22.                 free(q) ;
  23.         } else {
  24.                 printf("没有找到节点!\n")
  25.         }
  26.         return(p) ;
  27. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-22 17:46:44 | 显示全部楼层

这一段中我输入三个数,分别是11 22 22
得到的结果并不是我想象的那样,只删除第一个值,后面的值并没有删除

                               
登录/注册后可看大图
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-9-22 23:30:08 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2019-9-23 00:17 编辑
seglex 发表于 2019-9-22 17:46
这一段中我输入三个数,分别是11 22 22
得到的结果并不是我想象的那样,只删除第一个值,后面的值并没有 ...


      这是我系统地为你修改的代码,新增加了几个函数,你测试一下,看看能否解决你的问题。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. typedef struct student {
  5.         int num                        ;
  6.         char name[20]                  ;
  7.         struct student * pnext         ;
  8. } stu                                  ;

  9. int strip(char * s)
  10. {
  11.         int b , k , m                                                                               ;
  12.         m = strlen(s)                                                                               ;
  13.         while(m > 0 && (s[m - 1] == 0x07 || s[m - 1] == 0x0a || s[m - 1] == 0x0d || s[m - 1] == 0x20)) {
  14.                 s[m - 1] = 0x00                                                                     ;
  15.                 m --                                                                                ;
  16.         }
  17.         if(m > 0) {
  18.                 b = 0                                                                               ;
  19.                 while(b < m && (s[b] == 0x07 || s[b] == 0x0a || s[b] == 0x0d || s[b] == 0x20)) b ++ ;
  20.                 if(b > 0 && b < m) {
  21.                         for(k = b ; k < m ; k ++) s[k - b] = s[k]                                   ;
  22.                         s[m - b] = 0x00                                                             ;
  23.                         m -= b                                                                      ;
  24.                 }
  25.         }
  26.         return m                                                                                    ;
  27. }

  28. int getnum(int * num)
  29. {
  30.         int m , ret                                                ;
  31.         char s[260]                                                ;
  32.         ret = 0                                                    ;
  33.         * num = ret                                                ;
  34.         for(;;) {
  35.                 printf("输入学号 : ")                              ;
  36.                 fgets(s , 256 , stdin)                             ;
  37.                 if(strip(s)) {
  38.                         if(sscanf(s , "%d" , & m) == 1) {
  39.                                 ret = m                            ;
  40.                                 * num = ret                        ;
  41.                                 break                              ;
  42.                         } else {
  43.                                 fprintf(stderr , "输入错误!\n\n") ;
  44.                         }
  45.                 } else {
  46.                         break                                      ;
  47.                 }
  48.         }
  49.         return ret                                                 ;
  50. }

  51. char * getname(char * name)
  52. {
  53.         char s[260] , * ret                                        ;
  54.         name[0] = '\0'                                             ;
  55.         ret = name                                                 ;
  56.         printf("输入姓名 : ")                                      ;
  57.         fgets(s , 256 , stdin)                                     ;
  58.         if(strip(s)) strcpy(name , s)                              ;
  59.         return ret                                                 ;
  60. }

  61. stu * findnode(int num , stu * p)
  62. {
  63.         stu * ret                      ;
  64.         ret = NULL                     ;
  65.         while(p) {
  66.                 if(p -> num == num) {
  67.                         ret = p        ;
  68.                         break          ;
  69.                 } else {
  70.                         p = p -> pnext ;
  71.                 }
  72.         }
  73.         return ret                     ;
  74. }

  75. stu * addnode(stu * p)
  76. {
  77.         int num                                                                  ;
  78.         stu * h , * q                                                            ;
  79.         char name[20]                                                            ;
  80.         bool f                                                                   ;
  81.         f = true                                                                 ;
  82.         h = p                                                                    ;
  83.         printf("\n")                                                             ;
  84.         printf("*** 录入学员信息 ***\n")                                         ;
  85.         for(; f ;) {
  86.                 p = h                                                            ;
  87.                 printf("\n")                                                     ;
  88.                 if(getnum(& num)) {
  89.                         if(! findnode(num , p)) {
  90.                                 if(strlen(getname(name))) {
  91.                                         q = (stu *) malloc(sizeof(stu))          ;
  92.                                         q -> num = num                           ;
  93.                                         strcpy(q -> name , name)                 ;
  94.                                         q -> pnext = NULL                        ;
  95.                                         if(p) {
  96.                                                 while(p -> pnext) p = p -> pnext ;
  97.                                                 p -> pnext = q                   ;
  98.                                         } else {
  99.                                                 p = q                            ;
  100.                                                 h = p                            ;
  101.                                         }                                       
  102.                                 } else {
  103.                                         f = false                                ;
  104.                                 }
  105.                         } else {
  106.                                 fprintf(stderr , "错误:节点已经存在!\n\n")     ;
  107.                         }
  108.                 } else {
  109.                         f = false                                                ;
  110.                 }
  111.         }
  112.         return h                                                                 ;
  113. }

  114. stu * delnode(stu * p)
  115. {
  116.         int num                                                                                               ;
  117.         stu * h , * q                                                                                         ;
  118.         bool f                                                                                                ;
  119.         f = true                                                                                              ;
  120.         printf("\n")                                                                                          ;
  121.         printf("*** 删除学员信息 ***\n")                                                                      ;
  122.         h = p                                                                                                 ;
  123.         if(p) {
  124.                 for(; f ;) {
  125.                         if(h) {
  126.                                 p = h                                                                         ;
  127.                                 printf("\n")                                                                  ;
  128.                                 if(getnum(& num)) {
  129.                                         if((q = findnode(num , p))) {
  130.                                                 while(p != q && p -> pnext && p -> pnext != q) p = p -> pnext ;
  131.                                                 if(p == q || p -> pnext == q) {
  132.                                                         if(p == q) h = p -> pnext                             ;
  133.                                                         else p -> pnext = q -> pnext                          ;
  134.                                                         free(q)                                               ;
  135.                                                 }
  136.                                         } else {
  137.                                                 fprintf(stderr , "错误:节点未找到!\n\n")                    ;
  138.                                         }
  139.                                 } else {
  140.                                         f = false                                                             ;
  141.                                 }
  142.                         } else {
  143.                                 printf("\n")                                                                  ;
  144.                                 printf("链表节点已经全部删除!\n\n")                                          ;
  145.                                 f = false                                                                     ;
  146.                         }
  147.                 }
  148.         } else {
  149.                 fprintf(stderr , "错误:链表为空!\n\n")                                                      ;
  150.         }
  151.         return h                                                                                              ;
  152. }                    

  153. void print(stu * p)
  154. {
  155.         printf("\n")                                              ;
  156.         printf("*** 显示学员信息 ***\n")                          ;
  157.         if(p) {
  158.                 while(p) {
  159.                         printf("%d\t%s\n" , p -> num , p -> name) ;
  160.                         p = p -> pnext                            ;
  161.                 }
  162.         } else {
  163.                 fprintf(stderr , "错误:链表为空!\n\n")          ;
  164.         }
  165. }

  166. int main(void)
  167. {
  168.         stu * p        ;
  169.         p = NULL       ;
  170.         p = addnode(p) ;
  171.         print(p)       ;
  172.         p = delnode(p) ;
  173.         print(p)       ;
  174. }
复制代码

   
      这个代码花了比较大的力气在键盘输入检测方面,任何时候,如果从键盘获取的参数是空回车,则随时结束输入。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-25 09:51:11 | 显示全部楼层
jackz007 发表于 2019-9-22 23:30
这是我系统地为你修改的代码,新增加了几个函数,你测试一下,看看能否解决你的问题。

   

非常感谢,我会仔细阅读参考的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-7 09:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表