siberian_wolf 发表于 2014-12-24 18:12:15

又来求助问题了,这次是关于链表的

本帖最后由 siberian_wolf 于 2014-12-24 19:18 编辑

终于快要到教程的结束部分了,好高兴的说。可是又被卡住了,想了2天2夜了,求鱼油帮忙。都说旁观者清,望指点迷津。以下是代码:/*这是正常版本*/

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

#define LEN sizeof(struct student)//student结构的大小

int count_node;//列表中的节点数

struct student *creat_list();//创建链表
void print_list(struct student *head);   //打印链表
struct student *del_node(struct student *head);//删除节点
struct student *insert_node(struct student *head, struct student *new_node); //插入节点

struct student
{
      int num;
      float score;
      struct student *next;
};   

void main()
{
      struct student *stu, *insert, new_node;
      
      insert=stu = creat_list();
      print_list(stu);
      
/*start*/      
      printf("\nPlease input the num to insert:");
      scanf("%d", &new_node.num);//记录:如果用指针输入,由于没有初始化,会导致出错
      printf("\nPlease input the score:");
      scanf("%f", &new_node.score);
/*end*/

      insert= insert_node(insert,&new_node);
      print_list(insert);
      
      printf("\n\n");
      system("pause");
      
}

struct student *insert_node(struct student *head, struct student *new_node)
{
      struct student *p1, *p2, *p0;

      p1 = head;
      p0 = new_node;


      
   
      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(head == p1)//p1是头节点,插入头部
                  {
                        head = p0;
                        p0->next = p1;
                  }
                  else         //普通情况,插入中间
                  {
                        p2->next = p0;
                        p0->next = p1;
                  }
            }
            else               //p0最大,插入末尾
            {
                  p1->next = p0;
                  p0->next = NULL;
            }
      }
      
      count_node+=1;
      printf("\nInsert succeed!");
      
      return head;
}



struct student *creat_list()
{
      struct student *head, *p1, *p2;
      
      head=NULL;
      count_node=0;
      
      /*定义新节点并赋值*/
      
      p1=(struct student *)malloc(LEN);//LEN是student结构体的大小,(struct student *)是强制数据类型转换。
      printf("Please enter the num:");
      scanf("%d", &p1->num);
      printf("Please enter the score:");
      scanf("%f", &p1->score);
      
      p2=p1;    //p2移到最后一个节点
      
      
      while(p1->num)
      {
            count_node++;    //统计节点的个数
            if(1==count_node)
            {
                  head=p1;//head指向第一个元素
            }
            else
            {
                  p2->next=p1;   //链表最后一个元素指向新元素
            }
            
            p2=p1;    //p2移到链表末尾
            
            p1=(struct student *)malloc(LEN);      
            printf("\n\nPlease enter the num:");
            scanf("%d", &p1->num);
            printf("Please enter the score:");
            scanf("%f", &p1->score);
      }
      
      p2->next=NULL;
      
      return head;
}



void print_list(struct student *head)
{
      struct student *p;
      p=head;
      
      printf("\n\nThere are %d records!\n\n", count_node);
      
      if(NULL != head)
      {
            do
            {
                  printf("学号为 %d 的学生的分数是: %.2f\n", p->num, p->score);
                  p=p->next;
            }while(p);
      }
      else
      {
            printf("无学生数据!");
      }   
}

-----------------------------------------------------------------------------------------------------------------------------------------------------------
/*问题版本*/

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

#define LEN sizeof(struct student)//student结构的大小

int count_node;//列表中的节点数

struct student *creat_list();//创建链表
void print_list(struct student *head);   //打印链表
struct student *del_node(struct student *head);//删除节点

struct student *insert_node(struct student *head); //插入节点

struct student
{
      int num;
      float score;
      struct student *next;
};   

void main()
{
      struct student *stu, *insert, new_node;
      
      insert=stu = creat_list();
      print_list(stu);
      


      insert= insert_node(insert);
      print_list(insert);
      
      printf("\n\n");
      system("pause");
      
}

struct student *insert_node(struct student *head)
{
      struct student *p1, *p2, *p0;
两个版本的区别是:把正常版本start-end部分(就是新插入节点的输入部分)挪到了插入函数(insert _node)内部,这样做的好处是每次需要添加新节点的时候就直接调用这个函数就好了,不需要在主函数中出现赋值语句。但是问题来了,移到内部后可以正常执行,但是执行完插入后再打印这个列表就出现了问题。请大家帮忙分析分析。(在写这个文章的时候突然想到了,难道跟变量的生存周期有关??)

siberian_wolf 发表于 2014-12-24 19:01:22

本帖最后由 siberian_wolf 于 2014-12-24 19:19 编辑

哎,没人来吗?自己回去顺着思路想了一下,又翻看了,小甲鱼老师的课件,发现好像真的是变量的生存周期有问题。只要在问题版本定义new_node为static即可正常运行。或者是采用malloc函数方式申请空间就可以啦!!!这个问题困扰了我2天1夜突然间解决掉了,感觉好兴奋的!!保留此帖留作纪念,希望给后来者提供经验,也给自己留下一个难忘的节点。
页: [1]
查看完整版本: 又来求助问题了,这次是关于链表的