美文网首页
2018-12-08

2018-12-08

作者: 那年2018 | 来源:发表于2018-12-08 21:05 被阅读0次

课程设计功能大致分为功能菜单,增,删,改,查,排序,文件的保存与读取。下面便一一说明。

1.创建一个动态链表

struct student *create(struct student *head) //返回一个指向量表头指针的函数

{

struct student *p1 = NULL; //p1保存创建的新节点的地址

struct student *p2 = NULL; //p2保存原链表最后一个节点的地址

n = 0;

p1 = (struct student *) malloc (len);

p2 = p1;

if(p1==NULL)

{

    printf ("\n不能开辟节点\n");

    return NULL;

}

else

{

    head = NULL;     //避免它是一个野指针

    p1->zong=0;

    printf ("请输入学生学号:\n\t ");

    scanf ("%d", &(p1->num)); //录入数据

    printf("请输入学生姓名:\n\t");

    scanf("%s",(p1->name));

    for(int i=0; i<2; i++)

    {

        printf("请输入第%d门分数\n\t",i+1);

        scanf("%d",&(p1->score[i]));

        p1->zong=p1->zong+p1->score[i];

    }

}

while(p1->num != 0)//当学号不为0是继续录入信息

{

    n=n+1;         //节点总数增加1个

    if(n == 1)              //第一个节点需要特殊操作

    {

        head = p1;

        p2->next = NULL;

    }

    else

    {

        p2->next = p1;  //指向上次下面刚刚开辟的新节点

    }

    p2 = p1;     //把p1的地址给p2保留,然后p1产生新的节点

    p1=(struct student *)malloc(len);

    p1->zong=0;

    printf ("请输入学生学号:\n\t ");

    scanf ("%d", &(p1->num)); //录入数据

    printf("请输入学生姓名:\n\t");

    scanf("%s",(p1->name));

    for(int i=0; i<2; i++)

    {

        printf("请输入第%d门分数\n\t",i+1);

        scanf("%d",&(p1->score[i]));

        p1->zong=p1->zong+p1->score[i];

    }

}

p2->next = NULL; //此句就是根据单向链表的最后一个节点要指向NULL

return head;             //返回创建链表的头指针

}

这便是创建一个新链表的过程,首先这是一个返回指针的函数,第一步先判断链表是否为空,若不为空开辟一个空间并输入第一个学生的数据,然后判断此学生的学号是否为零(若为零链表停止增加,若不为零则增加节点)下面便是链表增加的核心内容:

    n=n+1;

    if(n == 1)            

    {

        head = p1;

        p2->next = NULL;

    }

    else

    {

        p2->next = p1;

    }

    p2 = p1;

    p1=(struct student *)malloc(len);

节点不断被创建,到结束时令p2->next=NULL;并请返回头指针。

2.删除节点

核心就是找到该节点,然后将该节点前驱和下一个节点连接,最后利用free函数将其释放,从而达到删除的目的。

查找:

p1=head;

while(p1->num!=num&&p1->next!=NULL)

{

    p2=p1;//若该项不是切换到下一项

    p1=p1->next;

}

不多说了上代码。

struct student *cut(struct student *head)//按照学号删除

{

int num;

printf("请输入要删除的学号:\n\t");

scanf("%d",&num);

struct student  *p1,*p2;

if(head==NULL)

{

    printf("此链表为空链表");

    return head;

}

p1=head;//从第一处开始排查

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;//将目标前端和后端连接在一起

    }

    free(p1);

    p1=NULL;

    printf("删除成功\n");

    n=n-1;

}

else

    printf("未找到%d",num);

return head;

}

3.输出数据

此功能是从第一个节点开始输出,然后自动移动到下一个节点并输出。

void print(struct student *head)

{

struct student *p;

printf("/学号  /姓名  /语文 /数学 /总分\n");

p=head;

if(head!=NULL)

{

    do

    {

        printf("%d  %s    %d    %d  %d\n",p->num,p->name,p->score[0],p->score[1],p->zong);

        p=p->next;

    }

    while(p!=NULL);

}

}

4.修改学生数据

这个的功能的实现其实也是靠查找,原先输入的的数据保存在缓存区中,现在只需再输入一次数据便可以将其覆盖,从而达到修改的目的。源代码如下:

struct student *change(struct student *head)

{

struct student *p1,*p2;

int no;

printf("请输入要求改学生的学号\n\t");

scanf("%d",&no);

p1=head;

while(no!=p1->num)

{

    p2=p1;

    p1=p1->next;

}

p1->zong=0;

printf ("请输入学生学号:\n\t ");

scanf ("%d", &(p1->num));

printf("请输入学生姓名:\n\t");

scanf("%s",(p1->name));

for(int i=0; i<2; i++)

{

    printf("请输入第%d门分数\n\t",i+1);

    scanf("%d",&(p1->score[i]));

    p1->zong=p1->zong+p1->score[i];

}

return head;

}

5.添加学生信息

这个功能是先开辟一个节点,再输入数据,然后将其连接在最后一个节点的后面。

struct student *add(struct student *head)

{

struct student *p1,*p2,*t;

p1=(struct student*)malloc(len);

p1->zong=0;

printf ("请输入学生学号:\n\t ");

scanf ("%d", &(p1->num));

printf("请输入学生姓名:\n\t");

scanf("%s",(p1->name));

for(int i=0; i<2; i++)

{

    printf("请输入第%d门分数\n\t",i+1);

    scanf("%d",&(p1->score[i]));

    p1->zong=p1->zong+p1->score[i];

}

p2=head;

while(p2!=NULL)

{

    t=p2;

    p2=p2->next;//寻找最后一个节点

}

t->next=p1;

p1->next=NULL;

n=n+1;//节点加一

return head;

}

6.搜索学生信息

先按条件查找出该节点,然后输出。

void search(struct student *head)

{

struct student *p1;

struct student *p2;

int no;

printf("请输入要查找的学号:\n\t");

scanf("%d",&no);

p1=head;

while(no!=p1->num)//依次排查

{

    p2=p1;

    p1=p1->next;

}

printf("/学号  /姓名  /语文 /数学 /总分\n");

printf("%d  %s    %d    %d  %d\n",p1->num,p1->name,p1->score[0],p1->score[1],p1->zong);

printf("搜索成功。");

}

7.排序

排序是课程设计的一个难点,在这里我选择了使用选择排序,就是利用选择排序不断找出链表中最大的节点然后将其给摘出来移到另一个链表中去,从而达到排序的目的。源代码如下:

struct student *sort (struct student *head)

{

struct student *first;//已排列好的链表第一个节点

struct student *last;//已排列好的链表最后一个节点

struct student *pt;

struct student *max;//最大节点

struct student *p;

first = NULL;

while(head != NULL)

{

    for (p = head, max = head; p->next != NULL; p = p->next)选择排序的体现

    {

        if (p->next->zong > max->zong)

        {

            pt = p;

            max = p->next;

        }

    }

    //令最大节点进入有序链表

    if (first == NULL)

    {

        first = max;

        last = max;

    }

    else

    {

        last->next = max;

        last = max;

    }

    //令最大节点离开原链表

    if (max == head)

    {

        head = head->next;

    }

    else

    {

        pt->next = max->next;

    }

}

if (first != NULL)

{

    last->next = NULL;

}

head = first;

return head;

}

8.保存数据

将链表中的数据闹存到文件中 要用到fprint()函数(格式化输入)此函数功能也比较容易实现。

ps:注意最后关闭文件。

void save(struct student *head)

{

FILE *fp;

if((fp=fopen("hello.txt","w"))==NULL)

{

    printf("文件写入失败");

    exit(1);

}

struct student *p1=head;

while(p1)

{

    fprintf(fp,"%d %s %d %d %d\n",p1->num,p1->name,p1->score[0],p1->score[1],p1->zong);//传送格式化输出到一个文件中与打印机输出

    p1=p1->next;

}

fclose(fp);

}

9.文件的读取

就是从系统的文件里读取数据,这和文件的保存有些相似点。但是也有很大不同,他是从文件格式化读取数据之后,放入一个空链表中。(fscanf的返回值实际上是读取数据的个数)

struct student *load(struct student *head)

{

head=(struct student*)malloc(len);

head->next=NULL;

FILE *fp;

if((fp=fopen("hello.txt","r"))==NULL)

{

    printf("文件打开失败\n");

    exit(1);

}

struct student *p;

struct student *t;

p=head;

while(fscanf(fp,"%d %s %d %d%d",&p->num,p->name,&p->score[0],&p->score[1],&p->zong)==5)

{

    t=p;

    p=(struct student*)malloc(len);

    t->next=p;

}

free(p);

t->next=NULL;

fclose(fp);

return head;

}

10.菜单函数

此功能最大作用就是调用各个函数,因此使用swich-case是一个好选择。再通过输入数字来选择功能。源代码如下:

int menu()

{

    int a;

    printf("请按任意键继续\n");

    getch();//暂停

    system("cls");

    printf("            学生成绩管理系统\n");

    printf("        ***********************\n");

    printf("        *1--------导入学生信息*\n");

    printf("        *2--------打印学生信息*\n");

    printf("        *3--------添加学生信息*\n");

    printf("        *4--------查找学生信息*\n");

    printf("        *5--------删除学生信息*\n");

    printf("        *6--------修改学生信息*\n");

    printf("        *7--------整理学生信息*\n");//按成绩排序

    printf("        *8--------保存学生信息*\n");

    printf("        *9--------读取成绩系统*\n");

    printf("        *10-------退出学生信息*\n");

    printf("        ***********************\n");

    printf("请选择功能\n");

    scanf("%d",&a);

    return a;

}

int main()

{

    struct student *head=NULL;

    while(1)

    {

        switch(menu())

        {

        case 1:

            head=create(head);

            break;

        case 2:

            print(head);

            break;

        case 3:

            head=add(head);

            break;

        case 4:

            search(head);

            break;

        case 5:

            head=cut(head);

            break;

        case 6:

            head=change(head);

            break;

        case 7:

            head=sort(head);

            break;

        case 8:

            save(head);

            break;

        case 9:

            head=load(head);

            break;

        case 10:

            exit(0);

            break;

        }

    }

    return 0;

}

课程设计到这里就结束了,第一次写还有很多漏洞还请指证。

相关文章

网友评论

      本文标题:2018-12-08

      本文链接:https://www.haomeiwen.com/subject/qpdchqtx.html