鱼C论坛

 找回密码
 立即注册
查看: 2393|回复: 1

[已解决]C语言中动态链表的问题

[复制链接]
发表于 2017-5-12 22:24:25 | 显示全部楼层 |阅读模式

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

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

x
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <conio.h>

#define MAX 100      //满分成绩
#define MIN 0           //最小成绩
#define LMN sizeof(struct student)
//student结构的大小
struct student *creat();           //创建链表
void print(struct student *head);  //打印链表
struct student *del( struct student *head, int num); //del函数用于删除节点,*head即链表的头指针,num是要删除的结点num。
struct student *insert( struct student *head, struct student *stu_2 );
//第一个参数需要被插入的链表。第二个参数待插入的结点的地址。


struct student
{
      long num;
      char name[20] ;
      float score;
      struct studen *next;
};

int n = 0;                                  //全局变量,用来记录存放了多少节点。
struct student *head = NULL;      
int main ()
{
      struct student * stu, *p, stu_2;
      long num;
      char ch;
      float s;
      s = MAX;
      
      printf("小写字母 z 键是删除数据,小写字母 x 键是插入数据!!\n输入其它键则退出程序!!!\n\n");
      printf("满分成绩为  %.1f 分!!!\n\n\n", s );
      
      
      stu = creat();
      p = stu;
      print(p);
      
#if(1)      
      printf("\n\n\n");
      
      while(1)
      { 
            ch = getch();
            if(ch == 'z' )
            {
                  printf("请输入需要删除的学号 : ");
                  scanf("%d", &num);
                  print( del(p, num));
            }
            else if ( ch == 'x' )
            {
                  printf("请输入新添加的学号 : ");
                  scanf("%d", &stu_2.num);
                  printf("请输入新添加的名字 : ");
                  scanf("%s", stu_2.name);
                  printf("请输入新添加的成绩 : ");
                  scanf("%f", &stu_2.score);
                  printf("\n");
                  while(1)
                  {
                        if( stu_2.score > MAX || stu_2.score < 0 )
                        {
                              printf("输入的成绩有误,请重新输入成绩 : ");
                              scanf("%f", &stu_2.score);
                        }
                        else
                        {
                              break;
                        }
                  }
                  
                  p = insert( stu, &stu_2);
                  print(p);
            }
            else 
            {
                  break;
            }
            
      }
#endif
      
      return 0;
}

struct student * creat(void)               //创建链表
{
      
      struct student *p1, *p2;
      
      
      p1 = p2 = ( struct student * ) malloc(LMN);
      
      
      printf("请输入学号 : ");
      scanf("%d", &p1->num);
      
      printf("请输入名字 : ");
      scanf("%s", p1->name);
      
      printf("请输入成绩 : ");
      scanf("%f", &p1->score);
      printf("\n");
      while(1)
      {
            if( p1->score > MAX || p1->score < 0  )
            {
                  printf("输入的成绩有误!\n请输入正确的成绩 : ");
                  scanf("%f", &p1->score);
                  printf("\n");
            }
            else
            {
                  break;
            }
      }
      
      
      
      while(p1->num != 0 )
      {
            n++;
            if( 1 == n )
            {
                  head = p1;
            }
            else
            {
                  p2->next = p1;
            }
            
            p2 = p1;
            p1 = (struct student * ) malloc(LMN);
            
            printf("请输入学号 : ");
            scanf("%d", &p1->num);
            printf("请输入名字 : ");
            scanf("%s", p1->name);
            printf("请输入成绩 : ");
            scanf("%f", &p1->score);
            printf("\n");
            if ( p1->score  > MAX || p1->score < 0 )
            {
                  printf("输入的成绩有误!!请输入正确的成绩 : ");
                  scanf("%f", &p1->score);
            }
      }
      
      p2->next = NULL;
      
      return (head);
}

void print(struct student *head)
{
      struct student *p;
      printf("\t现在这 %d 记录是 : \n", n );
      p = head;
      if(head != NULL)
      {
            do
            {
                  printf("\t学号 : %ld\t名字 : %s\t成绩 : %5.2f\n", p->num, p->name, p->score);
                  p = p->next;
            }while(p != NULL);
      }
}

#if(1)
struct student * del( struct student * head, int num )
{
      struct student *p1, *p2;
      
      if( head == NULL )
      {
            printf("这个列表为空!!\n");
            
            return head;
      }
      
      
      p1 = head;
      while ( p1->num != num && p1->next != NULL )
      {
            p2 = p1;
            p1 = p1->next;
      }
      if ( num == p1->num)
      {
            if ( head == p1 )
            {
                  head = p1->next;
            }
            else
            {
                  p2->next = p1->next;
            }
            
            printf("\n成功删除 NO : %d !!\n", num);
            n -= 1;
      }
      else
      {
            
            printf("没有找到匹配的数据 : %d !\n", num);
            
      }
      
      
      
      return head;
}

#endif

#if(1)
struct student *insert( struct student *head, struct student *stu_2)

{
      struct student *p1, *p2, *p0;
      
      p1 = head;
      p0 = stu_2;
      if( NULL == head )
      {
            head = p0;
            p0->next = NULL;
      }
      else
      {
            while( ( p0->num > p1->num) && ( p1->next != NULL) )
            {
                  p2 = p1;
                  p1 = p1->next;
            }
            if( p0->num <= p1->num)
            {
                  if( p1 == head )
                  {
                        head = p0;
                        p0->next = p1;
                  }
                  else
                  {
                        p2->next = p0;
                        p0->next = p1;
                  }
            }
            else
            {
                  p1->next = p0;
                  p0->next = NULL;
            }
      }
      n += 1;
      
      return head;
}

#endif


我在第二次输入x键实现第二次插入时发现上一次的插入的数据不会显示,但是节点数还是正确的。
大家可以运行下试着按两下x键 就会发现问题了。
帮我看看这要怎么修改了,现在脑子有点乱,。。。。
最佳答案
2017-5-13 18:30:26
本帖最后由 超凡天赐 于 2017-5-14 10:48 编辑

先说说你犯的最主要的错误,那就是你需要再写一个getchar()来接受你最后输入所留下的\n,为什么?因为getchar()和scanf("%c",&n)一样,也可以接受\n。详情见c语言学习笔记--chapter0-getchar,scanf以及缓冲区的概念-fontconfig-ChinaUnix博客 http://blog.chinaunix.net/uid-20568790-id-1632289.html。如果没有前面的getchar(),你最后只能退出这个程序。因为ch的值实际上是\n。当然了你还有其他一些问题,比如出现了long型向int型赋值,还有就是你为什么要使用条件编译?等等 ,好了废话不多说,
show you the code
#include <stdio.h>
#include <stdlib.h>
#define MAX 100      //满分成绩
#define MIN 0           //最小成绩
#define LMN sizeof(struct student)
//student结构的大小
struct student *create();           //创建链表
void print(struct student *head);  //打印链表
struct student *del( struct student *head, long num); //del函数用于删除节点,*head即链表的头指针,num是要删除的结点num。
struct student *insert( struct student *head, struct student *stu_2 );
//第一个参数需要被插入的链表。第二个参数待插入的结点的地址。
struct student
{
    long num;
    char name[20] ;
    float score;
    struct student *next;
};
int n = 0;                                  //全局变量,用来记录存放了多少节点。
struct student *head = NULL;
int main ()
{
    struct student * stu, *p, stu_2;
    long num;
    char ch;
    float s;
    s = MAX;
    printf("小写字母 z 键是删除数据,小写字母 x 键是插入数据!!\n输入其它键则退出程序!!!\n\n");
    printf("满分成绩为  %.1f 分!!!\n\n\n", s );
    stu = create();
    p = stu;
    print(p);
    printf("\n\n\n");
    getchar();
    while(1)
    {
        ch = getchar();
        if(ch == 'z' )
        {
            printf("请输入需要删除的学号 : ");
            scanf("%ld", &num);
            print( del(p, num));
        }
        else if ( ch == 'x' )
        {
            printf("请输入新添加的学号 : ");
            scanf("%ld", &stu_2.num);
            printf("请输入新添加的名字 : ");
            scanf("%s", stu_2.name);
            printf("请输入新添加的成绩 : ");
            scanf("%f", &stu_2.score);
            printf("\n");
            while(1)
            {
                if( stu_2.score > MAX || stu_2.score < 0 )
                {
                    printf("输入的成绩有误,请重新输入成绩 : ");
                    scanf("%f", &stu_2.score);
                }
                else
                {
                    break;
                }
            }
            p = insert( stu, &stu_2);
            print(p);
        }
        else
        {
            break;
        }
    }
    return 0;
}
struct student *create(void)               //创建链表
{
    struct student *p1, *p2;
    p1 = p2 = ( struct student * ) malloc(LMN);
    printf("请输入学号 : ");
    scanf("%ld", &p1->num);
    printf("请输入名字 : ");
    scanf("%s", p1->name);
    printf("请输入成绩 : ");
    scanf("%f", &p1->score);
    printf("\n");
    while(1)
    {
        if( p1->score > MAX || p1->score < 0  )
        {
            printf("输入的成绩有误!\n请输入正确的成绩 : ");
            scanf("%f", &p1->score);
            printf("\n");
        }
        else
        {
            break;
        }
    }
    while(p1->num != 0 )
    {
        n++;
        if( 1 == n )
        {
            head = p1;
        }
        else
        {
            p2->next = p1;
        }
        p2 = p1;
        p1 = (struct student * ) malloc(LMN);
        printf("请输入学号 : ");
        scanf("%ld", &p1->num);
        printf("请输入名字 : ");
        scanf("%s", p1->name);
        printf("请输入成绩 : ");
        scanf("%f", &p1->score);
        printf("\n");
        if ( p1->score  > MAX || p1->score < 0 )
        {
            printf("输入的成绩有误!!请输入正确的成绩 : ");
            scanf("%f", &p1->score);
        }
    }
    p2->next = NULL;
    return (head);
}
void print(struct student *head)
{
    struct student *p;
    printf("\t现在这 %d 记录是 : \n", n );
    p = head;
    if(head != NULL)
    {
        do
        {
            printf("\t学号 : %ld\t名字 : %s\t成绩 : %5.2f\n", p->num, p->name, p->score);
            p = p->next;
        }while(p != NULL);
    }
}
struct student *del( struct student * head,long num )
{
    struct student *p1, *p2 = NULL;
    
    if( head == NULL )
    {
        printf("这个列表为空!!\n");
        return head;
    }
    p1 = head;
    while ( p1->num != num && p1->next != NULL )
    {
        p2 = p1;
        p1 = p1->next;
    }
    if ( num == p1->num)
    {
        if ( head == p1 )
        {
            head = p1->next;
        }
        else
        {
            p2->next = p1->next;
        }
        
        printf("\n成功删除 NO : %ld !!\n", num);
        n -= 1;
    }
    else
    {
        printf("没有找到匹配的数据 : %ld !\n", num);
    }
    return head;
}
struct student *insert( struct student *head, struct student *stu_2)
{
    struct student *p1, *p2 = NULL, *p0;
    p1 = head;
    p0 = stu_2;
    if( NULL == head )
    {
        head = p0;
        p0->next = NULL;
    }
    else
    {
        while( ( p0->num > p1->num) && ( p1->next != NULL) )
        {
            p2 = p1;
            p1 = p1->next;
        }
        if( p0->num <= p1->num)
        {
            if( p1 == head )
            {
                head = p0;
                p0->next = p1;
            }
            else
            {
                p2->next = p0;
                p0->next = p1;
            }
        }
        else
        {
            p1->next = p0;
            p0->next = NULL;
        }
    }
    n += 1;
    return head;
}
我的测试结果为
小写字母 z 键是删除数据,小写字母 x 键是插入数据!!
输入其它键则退出程序!!!

满分成绩为  100.0 分!!!


请输入学号 : 1001
请输入名字 : zhutianci
请输入成绩 : 99

请输入学号 : 1002
请输入名字 : zhutian
请输入成绩 : 98

请输入学号 : 0
请输入名字 : 0
请输入成绩 : 0

        现在这 2 记录是 : 
        学号 : 1001        名字 : zhutianci        成绩 : 99.00
        学号 : 1002        名字 : zhutian        成绩 : 98.00



z
请输入需要删除的学号 : 1002

成功删除 NO : 1002 !!
        现在这 1 记录是 : 
        学号 : 1001        名字 : zhutianci        成绩 : 99.00
Program ended with exit code: 0
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-5-13 18:30:26 | 显示全部楼层    本楼为最佳答案   
本帖最后由 超凡天赐 于 2017-5-14 10:48 编辑

先说说你犯的最主要的错误,那就是你需要再写一个getchar()来接受你最后输入所留下的\n,为什么?因为getchar()和scanf("%c",&n)一样,也可以接受\n。详情见c语言学习笔记--chapter0-getchar,scanf以及缓冲区的概念-fontconfig-ChinaUnix博客 http://blog.chinaunix.net/uid-20568790-id-1632289.html。如果没有前面的getchar(),你最后只能退出这个程序。因为ch的值实际上是\n。当然了你还有其他一些问题,比如出现了long型向int型赋值,还有就是你为什么要使用条件编译?等等 ,好了废话不多说,
show you the code
#include <stdio.h>
#include <stdlib.h>
#define MAX 100      //满分成绩
#define MIN 0           //最小成绩
#define LMN sizeof(struct student)
//student结构的大小
struct student *create();           //创建链表
void print(struct student *head);  //打印链表
struct student *del( struct student *head, long num); //del函数用于删除节点,*head即链表的头指针,num是要删除的结点num。
struct student *insert( struct student *head, struct student *stu_2 );
//第一个参数需要被插入的链表。第二个参数待插入的结点的地址。
struct student
{
    long num;
    char name[20] ;
    float score;
    struct student *next;
};
int n = 0;                                  //全局变量,用来记录存放了多少节点。
struct student *head = NULL;
int main ()
{
    struct student * stu, *p, stu_2;
    long num;
    char ch;
    float s;
    s = MAX;
    printf("小写字母 z 键是删除数据,小写字母 x 键是插入数据!!\n输入其它键则退出程序!!!\n\n");
    printf("满分成绩为  %.1f 分!!!\n\n\n", s );
    stu = create();
    p = stu;
    print(p);
    printf("\n\n\n");
    getchar();
    while(1)
    {
        ch = getchar();
        if(ch == 'z' )
        {
            printf("请输入需要删除的学号 : ");
            scanf("%ld", &num);
            print( del(p, num));
        }
        else if ( ch == 'x' )
        {
            printf("请输入新添加的学号 : ");
            scanf("%ld", &stu_2.num);
            printf("请输入新添加的名字 : ");
            scanf("%s", stu_2.name);
            printf("请输入新添加的成绩 : ");
            scanf("%f", &stu_2.score);
            printf("\n");
            while(1)
            {
                if( stu_2.score > MAX || stu_2.score < 0 )
                {
                    printf("输入的成绩有误,请重新输入成绩 : ");
                    scanf("%f", &stu_2.score);
                }
                else
                {
                    break;
                }
            }
            p = insert( stu, &stu_2);
            print(p);
        }
        else
        {
            break;
        }
    }
    return 0;
}
struct student *create(void)               //创建链表
{
    struct student *p1, *p2;
    p1 = p2 = ( struct student * ) malloc(LMN);
    printf("请输入学号 : ");
    scanf("%ld", &p1->num);
    printf("请输入名字 : ");
    scanf("%s", p1->name);
    printf("请输入成绩 : ");
    scanf("%f", &p1->score);
    printf("\n");
    while(1)
    {
        if( p1->score > MAX || p1->score < 0  )
        {
            printf("输入的成绩有误!\n请输入正确的成绩 : ");
            scanf("%f", &p1->score);
            printf("\n");
        }
        else
        {
            break;
        }
    }
    while(p1->num != 0 )
    {
        n++;
        if( 1 == n )
        {
            head = p1;
        }
        else
        {
            p2->next = p1;
        }
        p2 = p1;
        p1 = (struct student * ) malloc(LMN);
        printf("请输入学号 : ");
        scanf("%ld", &p1->num);
        printf("请输入名字 : ");
        scanf("%s", p1->name);
        printf("请输入成绩 : ");
        scanf("%f", &p1->score);
        printf("\n");
        if ( p1->score  > MAX || p1->score < 0 )
        {
            printf("输入的成绩有误!!请输入正确的成绩 : ");
            scanf("%f", &p1->score);
        }
    }
    p2->next = NULL;
    return (head);
}
void print(struct student *head)
{
    struct student *p;
    printf("\t现在这 %d 记录是 : \n", n );
    p = head;
    if(head != NULL)
    {
        do
        {
            printf("\t学号 : %ld\t名字 : %s\t成绩 : %5.2f\n", p->num, p->name, p->score);
            p = p->next;
        }while(p != NULL);
    }
}
struct student *del( struct student * head,long num )
{
    struct student *p1, *p2 = NULL;
    
    if( head == NULL )
    {
        printf("这个列表为空!!\n");
        return head;
    }
    p1 = head;
    while ( p1->num != num && p1->next != NULL )
    {
        p2 = p1;
        p1 = p1->next;
    }
    if ( num == p1->num)
    {
        if ( head == p1 )
        {
            head = p1->next;
        }
        else
        {
            p2->next = p1->next;
        }
        
        printf("\n成功删除 NO : %ld !!\n", num);
        n -= 1;
    }
    else
    {
        printf("没有找到匹配的数据 : %ld !\n", num);
    }
    return head;
}
struct student *insert( struct student *head, struct student *stu_2)
{
    struct student *p1, *p2 = NULL, *p0;
    p1 = head;
    p0 = stu_2;
    if( NULL == head )
    {
        head = p0;
        p0->next = NULL;
    }
    else
    {
        while( ( p0->num > p1->num) && ( p1->next != NULL) )
        {
            p2 = p1;
            p1 = p1->next;
        }
        if( p0->num <= p1->num)
        {
            if( p1 == head )
            {
                head = p0;
                p0->next = p1;
            }
            else
            {
                p2->next = p0;
                p0->next = p1;
            }
        }
        else
        {
            p1->next = p0;
            p0->next = NULL;
        }
    }
    n += 1;
    return head;
}
我的测试结果为
小写字母 z 键是删除数据,小写字母 x 键是插入数据!!
输入其它键则退出程序!!!

满分成绩为  100.0 分!!!


请输入学号 : 1001
请输入名字 : zhutianci
请输入成绩 : 99

请输入学号 : 1002
请输入名字 : zhutian
请输入成绩 : 98

请输入学号 : 0
请输入名字 : 0
请输入成绩 : 0

        现在这 2 记录是 : 
        学号 : 1001        名字 : zhutianci        成绩 : 99.00
        学号 : 1002        名字 : zhutian        成绩 : 98.00



z
请输入需要删除的学号 : 1002

成功删除 NO : 1002 !!
        现在这 1 记录是 : 
        学号 : 1001        名字 : zhutianci        成绩 : 99.00
Program ended with exit code: 0

评分

参与人数 1鱼币 +5 收起 理由
小甲鱼 + 5 认真回答,点个赞!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-28 04:46

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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