zoukankan      html  css  js  c++  java
  • [链表] 对链表与文件的结合使用的一点看法

    概要:

         指针、链表和文件是C语言中比较重要的三块内容,经过一年的学习,我们大多人已经比较好的掌握了这三个方面的使用。但是将链表和文件结合使用,好像还没有哪道题中有过,或者还没有哪个人做过。于是,我写这篇论文——链表与文件的结合使用,并尽自己所能介绍一些比较方便易懂的方法和实例,将它们较好的呈献在大多人面前,以增加大家对链表、指针和文件的理解,提高大家学习C的兴趣。

    正文:

    用数组存放数据的时候,需要事先确定数组的长度,并分配连续的内存空间,其长度不能动态的改变,在面临实际的情况时,如对某公司的员工数据进行记录时,当员工数目变化时,数组很难相应变化。而使用链表,可以动态的分配空间,可以解决这些问题。谈到链表,就必须说到数据结构。链表是一种比较简单的线性数据结构,它可以实现对存储空间动态分配(首先要指明的是数组里的数据是连续存放,而链表里的数据是非连续存放的)。

    链表是由许许多多的链表节点串联起来的,且每一个节点都应是相同的结构体类型。

    对于链表的操作主要是:1.建立链表 2.数据的查找和输出 3.求链表节点的个数 4.插入和删除一个节点 3.链表的合并。

    首先建立链表(以学生信息管理为例):

    #include <malloc.h>   //建立链表是需要动态开辟空间,其函数属于malloc.h头文件

    #include <stdio.h>

    Int NUM = 0;         //NUM 记录链表的节点数,即学生的个数

    Struct stu {

    Long num;

    Float score;

    Struct stu *next;

    };

    Typedef  struct stu Stu_link;

    1.建立链表的方法有两种:尾插法和头插法,在此我就以尾插法为例。

    其函数模块为:

    Stu_link *cre_link () {

    //当前链表的头指针和为指针,表明链表的状态为空

    Stu_link *head = NULL, *last = NULL;

    Stu_link *p;

    P = (Stu_link *)malloc(sizeof(Stu_link));   //开辟节点

    Printf("input the number : ");

    Scanf("%d", &p->num);

    Printf("input the score : ");

    Scanf("%d", &p->score);

    While(p->num)

    {

    If(head == NULL)

    {

    Head = p;

    Last = p;

    }

    Else

    {

    Last->next = p;

    Last = p;

    }

    P = (Stu_link *)malloc(sizeof(Stu_link));   //重新开辟一个节点

    Printf("input the number : ");

    Scanf("%d", &p->num);

    If(p->num)

    {

    Printf("input the score : ");

    Scanf("%d", &p->score);

    P->next = NULL;

    }

    }

    Return head;

    }

    这个函数在主函数中被调用,会产生许多连接的链表节点,直到num输入0结束。

    此时就可以用文件操作了。在输入节点信息的时候就一同将学生信息存入到文件中去了。

    操作如下:

    void  cre_link () {

    //当前链表的头指针和为指针,表明链表的状态为空

    Stu_link *head = NULL, *last = NULL;

    FILE *stu;

    Stu_link *p;

    /*文件名应由用户自定义,可用下面注视语句,为了下面叙述方便,暂时由我来定义*/

    /*Char filename[30];

    Printf("input file path and name.dat : ");

    Gets(filename);*/

     

    /*以写的方式打开一个二进制文件*/

    If((stu = fopen("D:\\tc\\stuinfo.dat", "wb")) == NULL)

    {

    Printf("cannot open this file .");

    Exit(0);

    }

    P = (Stu_link *)malloc(sizeof(Stu_link));   //开辟节点

    Printf("input the number : ");

    Scanf("%d", &p->num);

    Printf("input the score : ");

    Scanf("%d", &p->score);

    While(p->num)

    {

    Fwrite(p, sizeof(Stu_link), 1, stu); 

    NUM++;        //记录链表的节点

    If(head == NULL)

    {

    Head = p;

    Last = p;

    }

    Else

    {

    Last->next = p;

    Last = p;

    }

    P = (Stu_link *)malloc(sizeof(Stu_link));   //重新开辟一个节点

    Printf("input the number : ");

    Scanf("%d", &p->num);

    If(p->num)

    {

    Printf("input the score : ");

    Scanf("%d", &p->score);

    P->next = NULL;

    }

    }

    Fclose(stu);

    }

    这样就实现了在建立链表并输入学生信息的时候,同时也将信息写入文件了。

    2.单链表元素的遍历:

    单链表元素的遍历,即将每个链表元素的内容都输出来。其函数模块比较简单,如下:

    Void print_link(Stu_link *head)

    {

    Stu_link *p;

    P = head;

    While(p)

    {

    Printf("num: %5d score:%5.1f\n", p->num, p->score);

    P = p->next;

    }

    Printf("\n");

    }

    因为上面已经对输入的学生信息写入了文件,所以链表的输出可以打开那个文件进行读操作。

    Void print_link()

    {

    Stu_link *p;

    FILE *fp;

    If((fp = fopen("D:\\tc\\stuinfo.dat", "rb")) == NULL)

    {
    printf("cannot open the file\n");

    Exit(0);

    }

    While(!feof(fp))   // 将文件中的内容读出并输出来

    {

    P = (Stu_link *)malloc(sizeof(Stu_link));

    Fseek(fp, 0, SEEK_CUR);               //保持文件内部指针在当前位置,下次

    Fread(p, sizeof(Stu_link), 1, fp);           //读出时的位置就从当前位置开始

    Printf("num: %5d score: %d5.1f", p->num, p->score);

    Free(p);                        //释放p的空间,以节省内存,方便下次开辟

    }

    Fclose(fp);

    }

    3.链表元素的查找

    具体思路是将文件中的数据读出来,然后一个个比较,若出现相等的,则找到结果。若没有出现则没有找到。

    其函数模块为:

    Stu_link *search(int num)   //其中num为要查找的学生的学号,在主函数中输出

    {

    Stu_link *p;

    FILE *fp;

    If((fp = (fopen("D:\\tc\\stuinfo.dat", "rb")) == NULL)

    {

    Printf("cannot open the file.");

    Exit(0);

    }

    While(!feof(fp))

    {

    P = (Stu_link *)malloc(sizeof(Stu_link));

    Fseek(fp, 0, SEEK_CUR);

    Fread(p, sizeof(Stu_link), 1, fp);

    If(p->num == num)

    {

    Printf("find the student .\n");

    Fclose(fp);

    Return p;

    }

    }

        printf("not find the student.\n");

    free (p);

    Fclose(fp);

    Return NULL;

    }

    4.链表的插入

    链表的插入有两种方法,节点前插入和节点后插入,在此我就以节点后插入为例,因为它比较符合习惯,简单易懂。

    Void  insert(Stu_link newstu)   //将新增加的信息插入到文件结尾   

    {

    FILE *fp;

    If((fp = fopen("D:\\tc\\stuinfo.dat", "ab")) == NULL)

    {

    Printf("cannot open the file.\n");

    Exit(0);

    }

    If(fwrite(&newstu, sizeof(Stu_link), 1, fp) == sizeof(Stu_link))

    {

    Printf("insert successfully!");

    NUM++;

    }

    Fclose(fp);

    Return;

    }

    5.链表的删除

    因为输入的数据都已经写入到文件中了,所以删除链表节点的基本思路是将文件中的节点一个个读出来,并与想删除的那个数据进行比较,若相同则可以删除,若没有相同的则没有该学生。

    其函数模块如下:

    //先把文件中的数据全部读出来,然后对信息进行删除,再将信息重新写入到文件中去

    Void delete(int stunum)

    {

    FILE *fp;

    Stu_link *stu, *p;

    Int i = 0, record;

    Stu = (Stu_link *)calloc(NUM, sizeof(Stu_link);

    If((fp = fopen("D:\\tc\\stuinfo.dat", "rb+")) == NULL)

    {

    Printf("cannot open the file.\n");

    Exit(0);

    }

    Fread(stu, sizeof(Stu_link), NUM, fp);

    For(i = 0; i < NUM; i++)

    {

    If(stu[i].num == stunum)

    {

    Record = i;

    Break;

    }

    Stu[record + 1].next = stu[record ].next;

    Free(stu[record]);

    Fclose(fp);

    If((fp = fopen("D:\\tc\\stuinfo.dat", "wb")) == NULL)

    {

    Printf("cannot open the file.\n");

    Exit(0);

    }

    Fwrite(stu, sizeof(Stu_link), NUM, fp);

    Fclose(fp);

    }

     

    结尾:

    上面所写内容只是链表与文件的结合使用的一部分,但却实现了我写这篇文章的初衷,即编写一个简单的学生成绩管理系统,可以实现简单的学生和学生成绩管理,对数据进行增删改查。大一尚未学过数据结构,所以只能以链表这个简单的数据结构来做此题。由于水平有限,对其解释仍有不够之处,还望海谅。

    参考资料:《C语言宝典》

    附:“自己用以上只是做的一个简单的学生管理系统”

    #include <stdio.h>

    #include <alloc.h>

    int NUM = 0;

     

    typedef struct stu

    {

    int  num;

    float score;

    struct stu *next;

    }Stu_link;

     

    void  cre_link()

    {

    Stu_link *head = NULL, *last = NULL;

    FILE *stu;

    Stu_link *p;

    float score;

     

    /*Char filename[30];   */

          /*printf("input file path and name.dat : ");     */

    /*gets(filename);*/

     

    if((stu = fopen("E:\\tc\\stuinfo.dat", "wb")) == NULL)

    {

    printf("cannot open this file .");

    getch();

    exit(0);

    }

    p = (Stu_link *)malloc(sizeof(Stu_link));

    printf("input the number : ");

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

    if(!(p->num))

    {

    printf("NULL finished !\n");

    return ;

    }

    while(p->num)

    {

    printf("input the score : ");

    scanf("%f", &(p->score));

    fwrite(p, sizeof(Stu_link), 1, stu);

    NUM++;

    if(head == NULL)

    {

    head = p;

    last = p;

    }

    else

    {

    last->next = p;

    last = p;

    }

    p->next = NULL;

    p = (Stu_link *)malloc(sizeof(Stu_link));

    printf("input the number : ");

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

    }

    printf("create successfully!\n");

    fclose(stu);

    }

     

    void print_link()

    {

    Stu_link *p;

    int i=0;

    FILE *fp;

    if((fp = fopen("E:\\tc\\stuinfo.dat", "rb")) == NULL)

    {

    printf("cannot open the file\n");

    getch();

    exit(0);

    }

    while(!feof(fp) && i < NUM)

    {

    p = (Stu_link *)malloc(sizeof(Stu_link));

    fread(p, sizeof(Stu_link), 1, fp);

    i++;

    printf("num: %d score: %.2f\n", p->num, p->score);

    free(p);

    }

    fclose(fp);

    }

     

    void  search(int num)

    {

    Stu_link *p;

    FILE *fp;

    if((fp = fopen("E:\\tc\\stuinfo.dat", "rb")) == NULL)

    {

    printf("cannot open the file.");

    getch();

    exit(0);

    }

    while(!feof(fp))

    {

    p = (Stu_link *)malloc(sizeof(Stu_link));

    fread(p, sizeof(Stu_link), 1, fp);

    if(p->num == num)

    {

    printf("find the student .\n");

    printf("num: %d  score: %.2f \n", p->num, p->score);

    fclose(fp);

    return;

    }

    }

    printf("not find the student.\n");

    free (p);

    fclose(fp);

    }

     

    void  insert(Stu_link newstu)

    {

    FILE *fp;

    if((fp = fopen("E:\\tc\\stuinfo.dat", "ab")) == NULL)

    {

    printf("cannot open the file.\n");

    getch();

    exit(0);

    }

    if(fwrite(&newstu, sizeof(Stu_link), 1, fp))

    {

    printf("insert successfully!\n");

    NUM++;

    }

    fclose(fp);

    return;

    }

     

    void delete(int stunum)

    {

    FILE *fp;

    Stu_link *stu, *p;

    int i = 0, record;

    stu = (Stu_link *)calloc(NUM, sizeof(Stu_link));

    if((fp = fopen("E:\\tc\\stuinfo.dat", "rb+")) == NULL)

    {

    printf("cannot open the file.\n");

    getch();

    exit(0);

    }

    fread(stu, sizeof(Stu_link), NUM, fp);

    for(i = 0; i < NUM; i++)

    {

    if(stu[i].num == stunum)

    {

    record = i;

    break;

    }

    }

    NUM--;

    fclose(fp);

    if((fp = fopen("E:\\tc\\stuinfo.dat", "wb")) == NULL)

    {

    printf("cannot open the file.\n");

    getch();

    exit(0);

    }

    for(i=0;i<NUM;i++)

    {

    if(i==record) continue;

    fwrite(stu+i, sizeof(Stu_link), 1, fp);

    }

    printf("Delete successfully!\n");

    free(stu);

    fclose(fp);

    }

    main()

    {

    int search_num, del_num, choice;

    Stu_link newstu;

    void cre_link();

    void print_link();

    void search(int);

    void delete(int);

    void insert(Stu_link);

    clrscr();

    while(1)

    {

    printf("-----Menu-----\n");

    printf("  1. start\n");

    printf("  2. search\n");

    printf("  3. print\n");

    printf("  4. amount of stu\n");

    printf("  5. insert \n");

    printf("  6. delete a stu\n");

    printf("  7. save and end \n");

    printf("\n");

    printf("choose : ");

    scanf("%d", &choice);

     

    switch(choice)

    {

     case 1:

    printf("input num 0 to stop.\n");

    cre_link();

    getch();

    break;

     case 2:

    printf("input the number of the student: ");

    scanf("%d", &search_num);

    search(search_num);

    getch();

    break;

     case 3:

    printf("all students : \n");

    print_link();

    getch();

    break;

     case 4:

    printf("All students are %d . \n", NUM);

    getch();

    break;

     case 5:

    printf("input the new student's number: ");

    scanf("%d", &newstu.num);

    printf("input the new student's score: ");

    scanf("%f", &newstu.score);

    insert(newstu);

    getch();

    break;

     case 6:

    printf("input the delete student's number: ");

    scanf("%d", &del_num);

    delete(del_num);

    getch();

    break;

     case 7:

    printf("save successfully !\n");

    getch();

    exit(0);

    break;

     default:

    printf("select error ! again ...\n");

    break;

    }

    }

    }

    该程序可以初始化学生的信息,查询学生的信息,打印学生的信息,查询学生总数,插入学生信息,删除学生信息。学生信息只需输入一次就可以多吃使用,因为它是从文件中读出学生信息。可见用文件将信息保存是个很好的方法。当然程序还有不完善的地方,比如,倘若学号输入相同,应进行提示,但这与我这篇文章的论题无关,而且进行修改很简单,在此不作赘述。

     

  • 相关阅读:
    HDU 4278 Faulty Odometer 8进制转10进制
    hdu 4740 The Donkey of Gui Zhou bfs
    hdu 4739 Zhuge Liang's Mines 随机化
    hdu 4738 Caocao's Bridges tarjan
    Codeforces Gym 100187M M. Heaviside Function two pointer
    codeforces Gym 100187L L. Ministry of Truth 水题
    Codeforces Gym 100187K K. Perpetuum Mobile 构造
    codeforces Gym 100187J J. Deck Shuffling dfs
    codeforces Gym 100187H H. Mysterious Photos 水题
    windows服务名称不是单个单词的如何启动?
  • 原文地址:https://www.cnblogs.com/xufeiyang/p/1760599.html
Copyright © 2011-2022 走看看