黑马程序员技术交流社区

标题: [iOS] 链表编写一个学生管理系统程序遇到问题,请大神解决 [打印本页]

作者: 魔主    时间: 2015-4-22 21:43
标题: [iOS] 链表编写一个学生管理系统程序遇到问题,请大神解决

编写一个学生管理系统程序,用来记录学生的信息(包括姓名、年龄、性别、学号、分数),提供增加、删除、查询学生信息的入口。(C语言)
//链表编写一个学生管理系统程序遇到问题,请大神解决。main函数好像不对,然后只能添加1个学生信息,怎么解决?或者大神改进代码,谢谢。
链表编写一个学生管理系统程序遇到问题,请大神解决
http://bbs.itheima.com/thread-190232-1-1.html   
悬赏解决

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

//创建节点结构,记录学生的信息
struct student{
    char name[20]; //姓名
    int age;       //年龄
    char sex;        //性别
    int no;    //学号
    int score;     //分数
    struct student*next;    //指向下一个节点的指针
};


int count;      //链表长度,作用是表示链表中节点数量
//create函数创建列表,该函数将会返回链表头指针
struct student *create()
{
    struct student *head=NULL;    //初始化链表,头指针为空
    struct student *end,*new;     //end指向原来尾节点,new指向新创建节点
    int count=0;           //初始化链表长度
    end=new=(struct student*)malloc(sizeof(struct student));
    /*使用malloc函数分配内存,end与new都指向第一个分配的内存。malloc函数原型: void*malloc(unsigned int size);功能:是在内存中动态地分配一块size大小的内存空间,返回一个指针,该指针指向分配的内存空间,如果出现错误则返回NULL;
     类似函数:calloc函数,其原型:void*calloc(unsigned n,unsigned size),功能:在内存中动态分配n个长度size的连续空间数组,会返回一个指针,该指针指向动态分配的连续内存空间地址, 如果出现错误则返回NULL; */
    printf("请输入学生信息(包括姓名、年龄、性别、学号、分数):\n");
    scanf("%s",new->name);  //姓名
    scanf("%d",&new->age);  //年龄
    scanf("%c",&new->sex);   //性别
    scanf("%d",&new->no);   //学号
    scanf("%d",&new->score);   //分数
    while(new->no!=0){
        count++;                 //表示链表节点增加
        //判断新加入节点是否第一次加入节点
        if(count==1)
        { //第一次加入节点时,新节点为首节点也为最后一个节点
            new->next=head;   //先将新节点指向为空
            end=new;      //跟踪新加入的节点
            head=new;     //头指针指向首节点
        }
        else
        {//加入新节点时链表中已有节点
            new->next=NULL;      //新节点的指针为空
            end->next=new;        //原来尾节点指向新节点
            end=new;              //end指向新节点
        }
        new=(struct student*)malloc(sizeof(struct student));
        /*再次分配节点内存空间,然后再次向其中输入数据,通过while循环再次判断输入的数据是否符合节点的要求。当要求不适合时,执行下面的代码,调用free函数将不符合要求的节点空间进行释放*/
        scanf("%s",new->name);
        scanf("%d",&new->age);
        scanf("%c",&new->sex);
        scanf("%d",&new->no);
        scanf("%d",&new->score);
    }
    free(new);  //释放没有用到的空间
    /*free函数原型:void free(void*ptr);  功能:使用由指针ptr指向的内存区,使部分内存区能被其他变量使用。ptr是最近一次调用calloc或malloc函数返回的值。free函数无返回值。*/
    return head;
}
//以上通过动态分配内存空间的方式创建完成链表


void print(struct student*head)     //输出链表,查询信息
{
    struct student*temp;             //循环使用临时指针
    int n=1;                   //表示链表中节点的序号
    printf("学生管理系统共有%d人\n",count);
    printf("\n");
    temp=head;     //指针得到首节点的地址
    while(temp!=NULL)
    {
        printf("学号%d的学生信息如下:\n",n);   //输出学号
        printf("姓名:%s\n",temp->name);        //输出姓名
        printf("年龄:%d\n",temp->age);         //输出年龄
        printf("性别:%c\n",temp->sex);        //输出性别
        printf("分数:%d\n",temp->score);          //输出分数
        printf("\n");
        temp=temp->next;                        //移动临时节点到下一个节点
        n++;
    }
}
/*print函数将链表数据输出,其参数head表示链表头节点。函数中定义一个临时指针temp用来循环操作,定义整型变量i表示链表节点序号,然后将临时指针temp保存首节点地址。
while语句将所有节点中保存的数据都显示输出,其中每输出一个节点内容后,就移动temp指针指向下一个节点地址,当为最后一个节点时,所拥有的指针指向NULL,循环结束*/


//在链表头节点位置插入节点[有三种插入操作(链表头节点位置插入节点,某个节点位置进行,像创建结构时在链表后面添加节点),思路一样]
//向链表中添加节点
struct student *insert(struct student*head)
{
    struct student*new;       //指向新分配空间
    printf("增加学生信息(包括姓名、年龄、性别、学号、分数):\n");
    new=(struct student*)malloc(sizeof(struct student));    //分配内存空间,并返回指向该内存空间的指针
    scanf("%s",new->name);
    scanf("%d",&new->age);
    scanf("%c",&new->sex);
    scanf("%d",&new->no);
    scanf("%d",&new->score);
    new->next=head;   //新节点指针指向原来首节点
    head=new;      //头指针指向新节点
    count++;        //增加链表节点数量
    return head;     //返回头指针
}
/*链表的插入需要为插入的链表分配内存,然后向新节点输入数据,这样一个新节点就创建完成了。如果需要将这个节点插入链表中,首先需要将新节点的指针指向原来的首节点,保存首节点的地址,然后将头指针指向新节点,这样就完成节点的连接操作,最后增加链表的节点数量*/


//删除链表节点
void delete(struct student*head,int n)       //head表示头节点,n表示要删除节点序号或下标
{
    int i;                          //控制循环次数
    struct student*temp;             //临时指针
    struct student*p;              //表示要删除节点前的节点
    temp=head;                   //得到头节点
    p=temp;
    printf("删除学号为%d的学生\n",n);
    for(i=1;i<n;i++)           //for循环使temp指向要删除的节点
    {
        p=temp;
        temp=temp->next;
    }
    p->next=temp->next;        //连接删除节点两边节点
    free(temp);                  //释放要删除节点的内存空间
    count--;                    //减少链表中节点的元素个数
}
/*delete函数传递两个参数,head表示链表头指针,n表示要删除的节点在链表中位置。定义变量i用来控制循环次数,然后定义两个指针,分别表示要删除的节点和这个节点之前的节点。输出一行提示信息表示要进行删除操作,之后利用for语句进行循环操作找到要删除的节点,连接删除节点两边的节点,并使用free函数将temp指向的内存空间进行释放。之后在main函数中添加代码执行删除操作,将链表中第二个节点进行删除*/

     int main(){
     struct student*head;        //定义头节点
     head=creaead);                //创建节点
     head=insert(head);           //增加学生信息
     delete(head,1);              //删除学生信息,例如删除第二个节点操作
     print(head);                 //输出链表
     return 0;
     }




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2