| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6014 人关注过本帖
标题:有关链表(输入输出数据,并删除一个数据)的问题,head=p1和p1=head的区别 ...
只看楼主 加入收藏
弟大勿勃
Rank: 2
等 级:论坛游民
帖 子:186
专家分:59
注 册:2014-4-17
结帖率:81.82%
收藏
已结贴  问题点数:10 回复次数:35 
有关链表(输入输出数据,并删除一个数据)的问题,head=p1和p1=head的区别?
程序代码:
#include<stdio.h>
#include<stdlib.h>

#define LEN sizeof(struct student)
struct student *creat();
struct student *del();
int print();
//******************************************//
int n;
//******************************************//
struct student
{
    int num;
    
    float score;
    struct student *next;
};
//******************************************//
int main()
{
    struct student *p,*stu;
    int n;
    stu=creat();
    p=stu;
    
    print(p);
    printf("Please input the num to deleat:");
    scanf("%d",&n);
    print(del(p,n));
    
    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->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;
        }
        printf("\nDeleat NO:%d succesed!\n",num);
        n=n-1;
    
    }
    else
    {
        printf("%d not been found!\n",num);
    }
END:
    return(head);
}

2016-09-12 13:57
弟大勿勃
Rank: 2
等 级:论坛游民
帖 子:186
专家分:59
注 册:2014-4-17
收藏
得分:0 
上面注释里有我想问的问题,请大神看看指导一下!
2016-09-12 13:59
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
这是一个删除的函数,
 if(head==NULL)这句已经判断了head不是空链表。
p1=head;  如果反这来写head=p1,你认为p1指向哪呢。
2016-09-12 14:02
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
还有不是p1指向head,而是将head的值赋值给p1
2016-09-12 14:11
弟大勿勃
Rank: 2
等 级:论坛游民
帖 子:186
专家分:59
注 册:2014-4-17
收藏
得分:0 
回复 3楼 linlulu001
奥,这样啊,就是说让p1指向一个非空链表!那它下面那句:while(p1->num!=num && p1->next!=NULL)               
                                                      {
                                               p2=p1;
                                               p1=p1->next;
                                                   }  
是干嘛的啊?和删除一个数据有什么关系吗?难道仅仅是为了让p2和p1产生关系?
2016-09-12 14:12
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
以下是引用弟大勿勃在2016-9-12 14:12:43的发言:

奥,这样啊,就是说让p1指向一个非空链表!那它下面那句:while(p1->num!=num && p1->next!=NULL)               
                                                      {
                                               p2=p1;
                                               p1=p1->next;
                                                   }  
是干嘛的啊?和删除一个数据有什么关系吗?难道仅仅是为了让p2和p1产生关系?



不仅仅是让p2和p1产生联系,同时查找链表:p1->num==num;
优点:将删除的代码分成两个类,就不用每次循环都要进行逻辑判断是否存在要删除的结构体。
缺点也很明显,只能删除链表中一个结构体,当要删除多个结构体时,就必须重复调用该函数。
顺便提一句,能不用goto就不要用。

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

2016-09-12 14:39
弟大勿勃
Rank: 2
等 级:论坛游民
帖 子:186
专家分:59
注 册:2014-4-17
收藏
得分:0 
回复 6楼 linlulu001
那我想删除多个结构体的话,在主函数中怎样重复调用del函数?难道用while循环?或者用什么方法能更智能点。
2016-09-12 14:51
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
现在才完整的看你的代码,发现几处坏习惯:
1、struct student *del();
int print();这两个函数声明小括号里的参数没有了,这样写很多编译器提示错误。
2、int n;  这个可以说是全局变量,但是,你的代码里面又声明一个n,这是局部变量。稍不注意就会搞错
3、goto的使用,如果就是想试试它的功能,没什么好说的。多个goto的使用,会大大降低代码的可读性和增加维护难度。
2016-09-12 14:54
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
while(p1!=NULL)               
    {
        p2=p1;                                         //
      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;
    }
    p1=p1->next;
}

直接遍历链表就好了。只是每次调用这个函数都要遍历。
看自己想要达到什么目的,
当然,你也可以利用全局变量n在主函数写上一个n次循环的调用函数。在找声明一个变量,接收函数返回的一个值,就是如果查找到最后一个链表也没有找到要册除的结构体就直接跳出循环。避免无用的多次循环

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

2016-09-12 14:58
弟大勿勃
Rank: 2
等 级:论坛游民
帖 子:186
专家分:59
注 册:2014-4-17
收藏
得分:0 
回复 9楼 linlulu001
谢谢啊!但是我为什么用你给的代码不能实现同时删除多个结构体的功能啊?
2016-09-12 15:38
快速回复:有关链表(输入输出数据,并删除一个数据)的问题,head=p1和p1=head的 ...
数据加载中...
 
   



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

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