| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5944 人关注过本帖
标题:有关链表(输入输出数据,并删除一个数据)的问题,head=p1和p1=head的区别 ...
只看楼主 加入收藏
弟大勿勃
Rank: 2
等 级:论坛游民
帖 子:186
专家分:59
注 册:2014-4-17
收藏
得分:0 
回复 9楼 linlulu001
还是不会编写删除多个结构体的语句啊,自己编的每次循环都只能删除一个结构体,好悲哀!
2016-09-12 16:05
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 

while(p1!=NULL)               
    {                                        //
      if(p1->num==num)
    {
        if(p1==head)
        {
            head=p1->next;
        }
        else
        {
        p2->next=p1->next;
        }
        printf("\nDeleat NO:%d succesed!\n",num);
     n=n-1;
    }
    p2=p1;
    p1=p1->next;
}
你试试。
2016-09-12 16:18
弟大勿勃
Rank: 2
等 级:论坛游民
帖 子:186
专家分:59
注 册:2014-4-17
收藏
得分:0 
回复 12楼 linlulu001
不行啊,直接是调试错误!那个在主函数中循环调用del函数的方法怎么实现呢?我调用后每次链表都会初始化,就总是只能删除一个结构体,求解决我神!
2016-09-12 16:38
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
回复 13楼 弟大勿勃
我用goto改了下不知道行不行
loop:     while(p1->num!=num && p1->next!=NULL)               
     {
         p2=p1;                                         //
        p1=p1->next;                                //
    }
     if(p1->num==num)
     {
         if(p1==head)
         {
             head=p1->next;
         }
         else
         {
         p2->next=p1->next;
         p1=p2->next;
         }
         printf("\nDeleat NO:%d succesed!\n",num);
         n=n-1;
     
     }
     if(p1!=NULL)goto loop;
2016-09-12 17:18
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
#include<stdio.h>
#include<stdlib.h>

#define LEN sizeof(struct student)
struct student *creat();
struct student *del(struct student *head,int num);
int print(struct student *head);
//******************************************//
int n;
//******************************************//
struct student
{
    int num;
   
    float score;
    struct student *next;
};
//******************************************//
int main()
{
    struct student *p,*stu;
    int num;
    stu=creat();
    p=stu;
   
    print(p);
    printf("Please input the num to deleat:");
    scanf("%d",&num);
    print(del(p,num));
   
    printf("\n\n");
   system("pause");
   
}

//******************************************//
struct student *creat()
{
    struct student *head,*p1,*p2;
    p1=p2=(struct student*) malloc(LEN);
    printf("input the num: ");
    scanf("%d",&p1->num);
    printf("input the score: ");
    scanf("%f",&p1->score);
    head=NULL;
    n=0;
    while(p1->num!=0)
    {
        n++;
        if(n==1)
        {
            head=p1;                    //head指向p1
        }
        else
        {
        p2->next=p1;                        //p2指向p1
        }
        p2=p1;                              //除去p1,让p2代替p1
        p1=(struct student *)malloc(LEN);    //重新输入一个p1
        printf("input the num: ");
        scanf("%d",&p1->num);
        printf("input the score: ");
        scanf("%f",&p1->score);
    }
    p2->next=NULL;                                //p1   
    return head;
   
}
//******************************************//
int print(struct student *head)
{
    struct student *p;
    printf("There are %d records\n",n);
    printf("\t\tnumber\t\tscore\n");
    p=head;
    while(p!=NULL)
    {
        printf("\t\t%d\t\t%.2f\n",p->num,p->score);
        p=p->next;
    }
}
//******************************************//
struct student *del(struct student *head,int num)
{
    struct student *p1,*p2;
    if(head==NULL)
    {
        printf("\nThis list is null!\n");
        goto END;
    }
    p1=head;                                     //为什么这里是p1指向head而不是head指向p1            
   
while(p1!=NULL)               
{                                        //
      if(p1->num==num)
    {
        if(p1==head)
        {
            head=p1->next;
            free(p1);
            p1=head->next;
        }
        else
        {
        p2->next=p1->next;
        free(p1);
        p1=p2->next;
        }
        printf("\nDeleat NO:%d succesed!\n",num);
     n=n-1;
    }
   else
      {
        p2=p1;
     p1=p1->next;
   }
}
END:
    return(head);
}

这样就行了
2016-09-12 17:25
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
回复 14楼 ehszt
你那个是死循环,把if(p1!=NULL)改成if(p1->next!=NULL)就行了。
2016-09-12 17:31
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
回复 16楼 linlulu001
不是死循环:
loop:     while(p1->num!=num && p1->next!=NULL)               
      {
          p2=p1;                                         //
         p1=p1->next;                                //
     }
      if(p1->num==num)
      {
          if(p1==head)
          {
              head=p1->next;
          }
          else
          {
          p2->next=p1->next;   //p1->next==NULL时p2->next==NULL,于是p1==NULL跳出循环
          p1=p2->next;
          }
          printf("\nDeleat NO:%d succesed!\n",num);
          n=n-1;
      
      }
      if(p1!=NULL)goto loop;
如果把if(p1!=NULL)改成if(p1->next!=NULL)会造最后一项无法删除

[此贴子已经被作者于2016-9-12 18:10编辑过]

2016-09-12 18:04
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
回复 17楼 ehszt
你是对的。
改成if(p->next!=NULL)有可能会程序会崩溃。
2016-09-12 20:39
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:0 
程序代码:
struct student *del(struct student *head,int num)
{
    struct student *p1,*p2;
    if(head==NULL)
    {
        printf("\nThis list is null!\n");
        goto END;
    }
    p1=head;                                     //为什么这里是p1指向head而不是head指向p1 ,因为要给p1初始化,          

    while(p1->num!=num && p1->next!=NULL) //当p1为空或者p1->num==num跳出循环             

    {
        p2=p1;                                         //
        p1=p1->next;                                //
    }
    if(p1->num==num)//如果当前p1->num==num,执行删除。所以楼主的代码逻辑就是只找到一个符合条件的元素删除了就完了。如果程序存在多个要删除的元素就不行了
    {
        if(p1==head)
        {
            head=p1->next;
        }
        else
        {
        p2->next=p1->next;
        }
        printf("\nDeleat NO:%d succesed!\n",num);
        n=n-1;
  

    }
    else
    {
        printf("%d not been found!\n",num);
    }
END:
    return(head);
}
解决方法有很多,这里我修改楼主的部分代码实现如下。
程序代码:
struct student *del(struct student *head,int num)
{
    struct student *p1;//
    struct student *p2;//专门用来free()
    int Times=0;//用来统计被删除的元素个数
    if(head==NULL)
    {
        printf("\nThis list is null!\n");
        return NULL;//没必要非得用GOTO,直接return就行了。写多个return语句的程序看起来比GOTO的健壮得多
    }
    p1=head;                                     //为什么这里是p1指向head而不是head指向p1 ,因为要给p1初始化,       
    while( p1->num==num){p2=p1;p1=p1->next;free(p2);Times++;} //处理删除链表头部 的问题
    head=p1;//此时p1->num肯定不会等于num
    if(p1)  //如果p1为空,跳过下面的循环,主要还是为了避免p1==NULL时,访问p1->next导致程序异常终止   
    while(p1->next!=NULL){      
        if(p1->next->num==num){p2=p1->next;p1->next=p2->next;free(p2);Times++;}
      p1=p1->next;
    }
  
       if(Times)printf("\nDeleat NO:%d succesed!\n",num);
        else  
        printf("%d not been found!\n",num);

    return head ;//搞不懂你为什么要加括号
}

PS:以上代码还没有测试过,可能存在语法错误之类的,欢迎指正。其实,使用链表的时候,我通常都会令他在读数据的时候就被整理成为有序的,那样不管使用查找、删除什么的都会方便得多。






[此贴子已经被作者于2016-9-12 21:41编辑过]


φ(゜▽゜*)♪
2016-09-12 21:35
弟大勿勃
Rank: 2
等 级:论坛游民
帖 子:186
专家分:59
注 册:2014-4-17
收藏
得分:0 
回复 15楼 linlulu001
谢版主,不过今晚回去晚了,明天再好好看看你们的见解。不会的还得多问您啊!
2016-09-12 21:58
快速回复:有关链表(输入输出数据,并删除一个数据)的问题,head=p1和p1=head的 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014070 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved