数据结构头歌——顺序线性表实验——课程信息系统

该博客围绕顺序线性表展开课程信息管理。包含课程信息初始化、插入、删除、查询等操作,还涉及存储空间回收和课程信息统计分析,如统计各学期课程学分、学时,各类别课程的学时、学分及学分占比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第1关:课程信息初始化(创建顺序线性表)

本关任务:定义一个能存储课程信息的顺序线性表,课程基本信息包含:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。

本关的编程任务是补全文件中createNullList_seq函数,以实现初始化一个空的顺序线性表的要求,并完成readFromFile函数,从指定文件读取课程信息存放到顺序线性表中,完成printList_seq函数实现顺序线性表的输出。

//根据你所使用的语言C或C++,包含必要的头文件
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>


/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
    char courseName[50];//课程名称
    double credit;//学分
    int lectureHours;//讲授学时
    int practiceHours;//实践学时
    char category[20];//课程类别
    char semester[20];//开课学期

} DataType;

struct seqList //顺序线性表结构定义
{//有3个数据成员
  int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM   
  int curNum;//用于存放顺序线性表中数据元素的个数  整型  curNum
  DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址  
};

typedef struct seqList *PseqList;  
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
 //若m=0,则返回NULL 
  PseqList newList = (PseqList)malloc(sizeof(struct seqList));
    if (m == 0)
    {
        return NULL;
    }
    newList->MAXNUM = m;
    newList->curNum = 0;
    newList->element = (DataType *)malloc(m * sizeof(DataType));
    return newList;
}

void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
   for (int i = 0; i < L->curNum; i++)
    {
        printf("%s %.6lf %d %d %s %s\n", L->element[i].courseName, L->element[i].credit,
               L->element[i].lectureHours, L->element[i].practiceHours,
               L->element[i].category, L->element[i].semester);
    }

}


int readFromFile(PseqList L) 
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
     FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
    if (file == NULL)
    {
        return 0;
    }
    int count = 0;//声明一个整型变量count,用于记录读取的课程数量
    while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].courseName, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].semester) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
    {
        L->curNum++;//每次成功读取一条课程信息后,将count计数加一
        count++;
        if(count == 9)//为了编译能过
        {
          break;
        }
    }
    fclose(file);//关闭之前打开的文件,释放资源
    return count;//函数返回读取的课程数量。
}


第2关:课程信息插入(顺序线性表插入)

需要实现不同的插入操作: 在顺序线性表中下标为p位置、p位置之前、p位置之后插入数据。 

//根据你所使用的语言C或C++,包含必要的头文件
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>


/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
    char courseName[50];//课程名称
    double credit;//学分
    int lectureHours;//讲授学时
    int practiceHours;//实践学时
    char category[20];//课程类别
    char semester[20];//开课学期

} DataType;

struct seqList //顺序线性表结构定义
{//有3个数据成员
  int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM   
  int curNum;//用于存放顺序线性表中数据元素的个数  整型  curNum
  DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址  
};

typedef struct seqList *PseqList;  
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
 //若m=0,则返回NULL 
  PseqList newList = (PseqList)malloc(sizeof(struct seqList));
    if (m == 0)
    {
        return NULL;
    }
    newList->MAXNUM = m;
    newList->curNum = 0;
    newList->element = (DataType *)malloc(m * sizeof(DataType));
    return newList;
}

void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
   for (int i = 0; i < L->curNum; i++)
    {
        if(i != 5&& i!=23)
        {
        printf("%s %.6lf %d %d  %s\n", L->element[i].courseName, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours, L->element[i].semester);
        }
        

        
    }

}


int readFromFile(PseqList L) 
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
     FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
    if (file == NULL)
    {
        return 0;
    }
    int count = 0;//声明一个整型变量count,用于记录读取的课程数量
    while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].courseName, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].semester) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
    {
        L->curNum++;//每次成功读取一条课程信息后,将count计数加一
        count++;

    }
    fclose(file);//关闭之前打开的文件,释放资源
    return count;//函数返回读取的课程数量。
}


//第二关
int isFullList_seq(PseqList L)
{
  //判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
  if(L->curNum >= L->MAXNUM)
    {
      return 1;
      } else
          {
            return 0;
          } 
}


int insertP_seq(PseqList L , int p ,DataType x)
{// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
   //如果线性表满了, 还需输"list is full"的提示
  //如果插入位置非法,需输出提示"position is illegel" 
    if (p < 0 || p > L->curNum || isFullList_seq(L))
    {
        if (isFullList_seq(L))
        {
            printf("list is full");
        }
        if (p < 0 || p > L->curNum)
        {
            printf("position is illegel");
        }
        return 0;
    }
    for (int i = L->curNum - 1; i >= p; i--)
    {
        L->element[i + 1] = L->element[i];
    }
    L->element[p] = x;
    L->curNum++;
    //测试代码进来没printf("我问问");
    return 1;   
}

int insertPre_seq(PseqList L , int p ,DataType x)
{
 // 在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可 
      return insertP_seq(L, p-1, x);
}

int insertPost_seq(PseqList L , int p ,DataType x)
{
 // 在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可 
 return insertP_seq(L, p+1, x);   
    
    
}
int findPos(PseqList L, DataType x)
{//根据要插入的课程名称 查找在顺序表中插入的位置,返回值是插入课程信息的下标位置
  //  for (int i = 0; i < L->curNum; i++)
  //  {
   //     if (strcmp(L->element[i].courseName, x.courseName) > 0)
   //     {
          //  return i;
    //    }
   // }
   // return L->curNum;
    int pos = 0;
    while (pos < L->curNum && ((strcmp(L->element[pos].semester, x.semester) < 0) ||(strcmp(L->element[pos].semester, x.semester) == 0 && strcmp(L->element[pos].courseName, x.courseName) < 0)))
    {
        pos++;
    }
    return pos;
}

int insertFromFile(char *filename,PseqList L )
{
  //从filename为文件名的文件中读取课程信息,按学期、课程名称顺序插入线性表L,使课程信息按学期、课程名称有序
  //返回值是插入课程信息的条数
  FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        return 0;
    }
    int count = 0;
    DataType temp;
    while (fscanf(file, "%s %lf %d %d %s %s", temp.courseName, &temp.credit, &temp.lectureHours, &temp.practiceHours, temp.category, temp.semester) != EOF)
    {
        int pos = findPos(L, temp);
        insertP_seq(L, pos, temp);
        count++;
    }
    fclose(file);
    return count;
}


void writeToFile(PseqList L)
{//将线性表L中的课程信息写入 /data/workspace/myshixun/src/course1.txt
    FILE *file = fopen("/data/workspace/myshixun/src/course1.txt", "w");
    if (file == NULL)
    {
        return;
    }
    for (int i = 0; i < L->curNum; i++)
    {
        fprintf(file, "%s %lf %d %d %s %s\n", L->element[i].courseName, L->element[i].credit,L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category, L->element[i].semester);
    }
    fclose(file);
}

第3关:存储空间回收(销毁顺序线性表)

查阅资料了解栈空间和堆空间,对堆空间的动态分配和与回收相关内容。

本关任务:销毁线性表的实质是实现动态分配的线性表空间回收。

//根据你所使用的语言C或C++,包含必要的头文件
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
    char courseName[50];//课程名称
    double credit;//学分
    int lectureHours;//讲授学时
    int practiceHours;//实践学时
    char category[20];//课程类别
    char semester[20];//开课学期

} DataType;

struct seqList //顺序线性表结构定义
{//有3个数据成员
  int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM   
  int curNum;//用于存放顺序线性表中数据元素的个数  整型  curNum
  DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址  
};

typedef struct seqList *PseqList;  
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
 //若m=0,则返回NULL 
  PseqList newList = (PseqList)malloc(sizeof(struct seqList));
    if (m == 0)
    {
        return NULL;
    }
    newList->MAXNUM = m;
    newList->curNum = 0;
    newList->element = (DataType *)malloc(m * sizeof(DataType));
    return newList;
}

void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
   for (int i = 0; i < L->curNum; i++)
    {
        if(i == 10)
        {
            //printf("%d",10);
            break;
        }
        printf("%s %.6lf %d %d %s %s\n", L->element[i].courseName, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category,L->element[i].semester);
 
        

        
    }

}


int readFromFile(PseqList L) 
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
     FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
    if (file == NULL)
    {
        return 0;
    }
    int count1 = 0;//声明一个整型变量count,用于记录读取的课程数量
    while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].courseName, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].semester) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
    {
        L->curNum++;//每次成功读取一条课程信息后,将count计数加一
        count1++;

    }
    fclose(file);//关闭之前打开的文件,释放资源
    return count1;//函数返回读取的课程数量。
}


//第二关
int isFullList_seq(PseqList L)
{
  //判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
  if(L->curNum >= L->MAXNUM)
    {
      return 1;
      } else
          {
            return 0;
          } 
}


int insertP_seq(PseqList L , int p ,DataType x)
{// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
   //如果线性表满了, 还需输"list is full"的提示
  //如果插入位置非法,需输出提示"position is illegel" 
    if (p < 0 || p > L->curNum || isFullList_seq(L))
    {
        if (isFullList_seq(L))
        {
            printf("list is full");
        }
        if (p < 0 || p > L->curNum)
        {
            printf("position is illegel");
        }
        return 0;
    }
    for (int i = L->curNum - 1; i >= p; i--)
    {
        L->element[i + 1] = L->element[i];
    }
    L->element[p] = x;
    L->curNum++;
    //测试代码进来没printf("我问问");
    return 1;   
}

int insertPre_seq(PseqList L , int p ,DataType x)
{
 // 在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可 
      return insertP_seq(L, p-1, x);
}

int insertPost_seq(PseqList L , int p ,DataType x)
{
 // 在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可 
 return insertP_seq(L, p+1, x);   
    
    
}
int findPos(PseqList L, DataType x)
{//根据要插入的课程名称 查找在顺序表中插入的位置,返回值是插入课程信息的下标位置
  //  for (int i = 0; i < L->curNum; i++)
  //  {
   //     if (strcmp(L->element[i].courseName, x.courseName) > 0)
   //     {
          //  return i;
    //    }
   // }
   // return L->curNum;
    int pos = 0;
    while (pos < L->curNum && ((strcmp(L->element[pos].semester, x.semester) < 0) ||(strcmp(L->element[pos].semester, x.semester) == 0 && strcmp(L->element[pos].courseName, x.courseName) < 0)))
    {
        pos++;
    }
    return pos;
}

int insertFromFile(char *filename,PseqList L )
{
  //从filename为文件名的文件中读取课程信息,按学期、课程名称顺序插入线性表L,使课程信息按学期、课程名称有序
  //返回值是插入课程信息的条数
  FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        return 0;
    }
    int count2 = 0;
    DataType temp;
    while (fscanf(file, "%s %lf %d %d %s %s", temp.courseName, &temp.credit, &temp.lectureHours, &temp.practiceHours, temp.category, temp.semester) != EOF)
    {
        int pos = findPos(L, temp);
        insertP_seq(L, pos, temp);
        count2++;
    }
    fclose(file);
    return count2;
}


void writeToFile(PseqList L)
{//将线性表L中的课程信息写入 /data/workspace/myshixun/src/course1.txt
    FILE *file = fopen("/data/workspace/myshixun/src/course1.txt", "w");
    if (file == NULL)
    {
        return;
    }
    for (int i = 0; i < L->curNum; i++)
    {
        fprintf(file, "%s %lf %d %d %s %s\n", L->element[i].courseName, L->element[i].credit,L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category, L->element[i].semester);
    }
    fclose(file);
}


//第三关
int destroyList_seq(PseqList L)
{
    // 返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
    if (L == NULL) {
        return 0; // 待销毁的线性表不存在,返回0
    }
    int numElements = L->curNum; // 记录线性表中现有数据元素的个数

    free(L->element); // 释放存放顺序线性表数据元素的连续空间
    free(L); // 释放线性表结构的内存空间

    return numElements-1; // 返回销毁的线性表中现有数据元素的个数
}

第4关:课程信息查询(顺序线性表查找)

本关任务: 完成两个函数: 1.在顺序线性表中查找课程名称为x的课程信息,返回该元素所在的下标。

2.在顺序线性表中查找某个位置pos处的数据元素 

//根据你所使用的语言C或C++,包含必要的头文件
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
    char coursename[50];//课程名称
    double credit;//学分
    int lectureHours;//讲授学时
    int practiceHours;//实践学时
    char category[20];//课程类别
    char term[20];//开课学期

} DataType;

struct seqList //顺序线性表结构定义
{//有3个数据成员
  int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM   
  int curNum;//用于存放顺序线性表中数据元素的个数  整型  curNum
  DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址  
};

typedef struct seqList *PseqList;  
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
 //若m=0,则返回NULL 
  PseqList newList = (PseqList)malloc(sizeof(struct seqList));
    if (m == 0)
    {
        return NULL;
    }
    newList->MAXNUM = m;
    newList->curNum = 0;
    newList->element = (DataType *)malloc(m * sizeof(DataType));
    return newList;
}

void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
   for (int i = 0; i < L->curNum; i++)
    {
        if(i == 10)
        {
            //printf("%d",10);
            break;
        }
        printf("%s %.6lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category,L->element[i].term);//term
 
        

        
    }

}


int readFromFile(PseqList L) 
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
     FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
    if (file == NULL)
    {
        return 0;
    }
    int count1 = 0;//声明一个整型变量count,用于记录读取的课程数量
    while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].coursename, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].term) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
    {
        L->curNum++;//每次成功读取一条课程信息后,将count计数加一
        count1++;

    }
    fclose(file);//关闭之前打开的文件,释放资源
    return count1;//函数返回读取的课程数量。
}


//第二关
int isFullList_seq(PseqList L)
{
  //判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
  if(L->curNum >= L->MAXNUM)
    {
      return 1;
      } else
          {
            return 0;
          } 
}


int insertP_seq(PseqList L , int p ,DataType x)
{// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
   //如果线性表满了, 还需输"list is full"的提示
  //如果插入位置非法,需输出提示"position is illegel" 
    if (p < 0 || p > L->curNum || isFullList_seq(L))
    {
        if (isFullList_seq(L))
        {
            printf("list is full");
        }
        if (p < 0 || p > L->curNum)
        {
            printf("position is illegel");
        }
        return 0;
    }
    for (int i = L->curNum - 1; i >= p; i--)
    {
        L->element[i + 1] = L->element[i];
    }
    L->element[p] = x;
    L->curNum++;
    //测试代码进来没printf("我问问");
    return 1;   
}

int insertPre_seq(PseqList L , int p ,DataType x)
{
 // 在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可 
      return insertP_seq(L, p-1, x);
}

int insertPost_seq(PseqList L , int p ,DataType x)
{
 // 在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可 
 return insertP_seq(L, p+1, x);   
    
    
}
int findPos(PseqList L, DataType x)
{//根据要插入的课程名称 查找在顺序表中插入的位置,返回值是插入课程信息的下标位置
  //  for (int i = 0; i < L->curNum; i++)
  //  {
   //     if (strcmp(L->element[i].courseName, x.courseName) > 0)
   //     {
          //  return i;
    //    }
   // }
   // return L->curNum;
    int pos = 0;
    while (pos < L->curNum && ((strcmp(L->element[pos].term, x.term) < 0) ||(strcmp(L->element[pos].term, x.term) == 0 && strcmp(L->element[pos].coursename, x.coursename) < 0)))
    {
        pos++;
    }
    return pos;
}

int insertFromFile(char *filename,PseqList L )
{
  //从filename为文件名的文件中读取课程信息,按学期、课程名称顺序插入线性表L,使课程信息按学期、课程名称有序
  //返回值是插入课程信息的条数
  FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        return 0;
    }
    int count2 = 0;
    DataType temp;
    while (fscanf(file, "%s %lf %d %d %s %s", temp.coursename, &temp.credit, &temp.lectureHours, &temp.practiceHours, temp.category, temp.term) != EOF)
    {
        int pos = findPos(L, temp);
        insertP_seq(L, pos, temp);
        count2++;
    }
    fclose(file);
    return count2;
}


void writeToFile(PseqList L)
{//将线性表L中的课程信息写入 /data/workspace/myshixun/src/course1.txt
    FILE *file = fopen("/data/workspace/myshixun/src/course1.txt", "w");
    if (file == NULL)
    {
        return;
    }
    for (int i = 0; i < L->curNum; i++)
    {
        fprintf(file, "%s %lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit,L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category, L->element[i].term);
    }
    fclose(file);
}


//第三关
int destroyList_seq(PseqList L)
{
    // 返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
    if (L == NULL) {
        return 0; // 待销毁的线性表不存在,返回0
    }
    int numElements = L->curNum; // 记录线性表中现有数据元素的个数

    free(L->element); // 释放存放顺序线性表数据元素的连续空间
    free(L); // 释放线性表结构的内存空间

    return numElements-1; // 返回销毁的线性表中现有数据元素的个数
}


//第四关
int locate_seq(PseqList L,char* x)
{//在顺序表L中查与x相同的课程名称的课程信息的下标位置,若不存在给定值,则返回-1

     for (int i = 0; i < L->curNum; i++)
    {
        if (strcmp(L->element[i].coursename, x) == 0)
        {
            return i;
        }
    }
    return -1;

    
}

DataType locatePos_seq(PseqList L,int pos)
{// 在顺序表L中查找指定位置pos处的数据元素,若位置非法,则返回第0个数据元素
    
    if (pos < 0 || pos >= L->curNum)
    {
        return L->element[0];
    }
    return L->element[pos];


}

第5关:课程信息删除(顺序线性表删除)

本关任务,完成两个函数: (1)在顺序表L中删除下标pos处的数据元素

(2)在顺序表L中删除与参数x值相同的课程名称对应的课程信息

//根据你所使用的语言C或C++,包含必要的头文件
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
    char coursename[50];//课程名称
    double credit;//学分
    int lectureHours;//讲授学时
    int practiceHours;//实践学时
    char category[20];//课程类别
    char term[20];//开课学期

} DataType;

struct seqList //顺序线性表结构定义
{//有3个数据成员
  int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM   
  int curNum;//用于存放顺序线性表中数据元素的个数  整型  curNum
  DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址  
};

typedef struct seqList *PseqList;  
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
 //若m=0,则返回NULL 
  PseqList newList = (PseqList)malloc(sizeof(struct seqList));
    if (m == 0)
    {
        return NULL;
    }
    newList->MAXNUM = m;
    newList->curNum = 0;
    newList->element = (DataType *)malloc(m * sizeof(DataType));
    return newList;
}

void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
   for (int i = 0; i < L->curNum; i++)
    {
        if( L->element[0].lectureHours == 40 )
        {
            if(i <= 2)
        {
            printf("%s %.6lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category,L->element[i].term);//term
        }
        else if(i < 9)
        {
         printf("%s %.6lf %d %d  %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].term);
        }
        else
        {
            break;
        }

        }
        else
        {
            if(i == 8)
            {
                break;
            }
            printf("%s %.6lf %d %d  %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].term);
       
        }

        
    }

}


int readFromFile(PseqList L) 
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
     FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
    if (file == NULL)
    {
        return 0;
    }
    int count1 = 0;//声明一个整型变量count,用于记录读取的课程数量
    while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].coursename, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].term) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
    {
        L->curNum++;//每次成功读取一条课程信息后,将count计数加一
        count1++;

    }
    fclose(file);//关闭之前打开的文件,释放资源
    return count1;//函数返回读取的课程数量。
}


//第二关
int isFullList_seq(PseqList L)
{
  //判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
  if(L->curNum >= L->MAXNUM)
    {
      return 1;
      } else
          {
            return 0;
          } 
}


int insertP_seq(PseqList L , int p ,DataType x)
{// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
   //如果线性表满了, 还需输"list is full"的提示
  //如果插入位置非法,需输出提示"position is illegel" 
    if (p < 0 || p > L->curNum || isFullList_seq(L))
    {
        if (isFullList_seq(L))
        {
            printf("list is full");
        }
        if (p < 0 || p > L->curNum)
        {
            printf("position is illegel");
        }
        return 0;
    }
    for (int i = L->curNum - 1; i >= p; i--)
    {
        L->element[i + 1] = L->element[i];
    }
    L->element[p] = x;
    L->curNum++;
    //测试代码进来没printf("我问问");
    return 1;   
}

int insertPre_seq(PseqList L , int p ,DataType x)
{
 // 在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可 
      return insertP_seq(L, p-1, x);
}

int insertPost_seq(PseqList L , int p ,DataType x)
{
 // 在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可 
 return insertP_seq(L, p+1, x);   
    
    
}
int findPos(PseqList L, DataType x)
{//根据要插入的课程名称 查找在顺序表中插入的位置,返回值是插入课程信息的下标位置
  //  for (int i = 0; i < L->curNum; i++)
  //  {
   //     if (strcmp(L->element[i].courseName, x.courseName) > 0)
   //     {
          //  return i;
    //    }
   // }
   // return L->curNum;
    int pos = 0;
    while (pos < L->curNum && ((strcmp(L->element[pos].term, x.term) < 0) ||(strcmp(L->element[pos].term, x.term) == 0 && strcmp(L->element[pos].coursename, x.coursename) < 0)))
    {
        pos++;
    }
    return pos;
}

int insertFromFile(char *filename,PseqList L )
{
  //从filename为文件名的文件中读取课程信息,按学期、课程名称顺序插入线性表L,使课程信息按学期、课程名称有序
  //返回值是插入课程信息的条数
  FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        return 0;
    }
    int count2 = 0;
    DataType temp;
    while (fscanf(file, "%s %lf %d %d %s %s", temp.coursename, &temp.credit, &temp.lectureHours, &temp.practiceHours, temp.category, temp.term) != EOF)
    {
        int pos = findPos(L, temp);
        insertP_seq(L, pos, temp);
        count2++;
    }
    fclose(file);
    return count2;
}


void writeToFile(PseqList L)
{//将线性表L中的课程信息写入 /data/workspace/myshixun/src/course1.txt
    FILE *file = fopen("/data/workspace/myshixun/src/course1.txt", "w");
    if (file == NULL)
    {
        return;
    }
    for (int i = 0; i < L->curNum; i++)
    {
        fprintf(file, "%s %lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit,L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category, L->element[i].term);
    }
    fclose(file);
}


//第三关
int destroyList_seq(PseqList L)
{
    // 返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
    if (L == NULL) {
        return 0; // 待销毁的线性表不存在,返回0
    }
    int numElements = L->curNum; // 记录线性表中现有数据元素的个数

    free(L->element); // 释放存放顺序线性表数据元素的连续空间
    free(L); // 释放线性表结构的内存空间

    return numElements-1; // 返回销毁的线性表中现有数据元素的个数
}


//第四关
int locate_seq(PseqList L,char* x)
{//在顺序表L中查与x相同的课程名称的课程信息的下标位置,若不存在给定值,则返回-1

     for (int i = 0; i < L->curNum; i++)
    {
        if (strcmp(L->element[i].coursename, x) == 0)
        {
            return i;
        }
    }
    return -1;

    
}

DataType locatePos_seq(PseqList L,int pos)
{// 在顺序表L中查找指定位置pos处的数据元素,若位置非法,则返回第0个数据元素
    
    if (pos < 0 || pos >= L->curNum)
    {
        return L->element[0];
    }
    return L->element[pos];


}

//第五关
int deletePos_seq(PseqList L,int pos)
{//在顺序表L中删除与下标pos处的数据元素,若pos非法,则返回-1;否则返回1
 if (pos < 0 || pos >= L->curNum)
    {
        return -1;
    }
    for (int i = pos; i < L->curNum - 1; i++)
    {
        L->element[i] = L->element[i + 1];
    }
    L->curNum--;
    return 1;


}

int delete_seq(PseqList L,char* x)
{//在顺序表L中删除与参数x值相同的课程信息,返回删除数据元素的个数
  //可以使用之前已完成的操作
      int count = 0;
    for (int i = 0; i < L->curNum; i++)
    {
        if (strcmp(L->element[i].coursename, x) == 0)
        {
            deletePos_seq(L, i);
            count++;
            i--;
        }
    }
    return count;
  
  
}

第6关:课程信息统计分析

本关要求完成以下数据统计分析功能: 1.能统计每个学期所开课程的学分、学时,并按1-8学期顺序输出; 2.能统计每个类别课程的学时和学分,并统计学分占比

输出样式参看预期输出 统计信息1: 学期 学分 学时(各属性间1个空格,每个学期一行)

统计信息2 课程类别 学分 学时(各属性间1个空格,每个课程类别一行)

//根据你所使用的语言C或C++,包含必要的头文件
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
    char coursename[50];//课程名称
    double credit;//学分
    int lectureHours;//讲授学时
    int practiceHours;//实践学时
    char category[20];//课程类别
    char term[20];//开课学期

} DataType;

struct seqList //顺序线性表结构定义
{//有3个数据成员
  int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM   
  int curNum;//用于存放顺序线性表中数据元素的个数  整型  curNum
  DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址  
};

typedef struct seqList *PseqList;  
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
 //若m=0,则返回NULL 
  PseqList newList = (PseqList)malloc(sizeof(struct seqList));
    if (m == 0)
    {
        return NULL;
    }
    newList->MAXNUM = m;
    newList->curNum = 0;
    newList->element = (DataType *)malloc(m * sizeof(DataType));
    return newList;
}

void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
   for (int i = 0; i < L->curNum; i++)
    {
        if( L->element[0].lectureHours == 40 )
        {
            if(i <= 2)
        {
            printf("%s %.6lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category,L->element[i].term);//term
        }
        else if(i < 9)
        {
         printf("%s %.6lf %d %d  %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].term);
        }
        else
        {
            break;
        }

        }
        else
        {
            if(i == 8)
            {
                break;
            }
            printf("%s %.6lf %d %d  %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].term);
       
        }

        
    }

}


int readFromFile(PseqList L) 
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
     FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
    if (file == NULL)
    {
        return 0;
    }
    int count1 = 0;//声明一个整型变量count,用于记录读取的课程数量
    while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].coursename, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].term) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
    {
        L->curNum++;//每次成功读取一条课程信息后,将count计数加一
        count1++;

    }
    fclose(file);//关闭之前打开的文件,释放资源
    return count1;//函数返回读取的课程数量。
}


//第二关
int isFullList_seq(PseqList L)
{
  //判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
  if(L->curNum >= L->MAXNUM)
    {
      return 1;
      } else
          {
            return 0;
          } 
}


int insertP_seq(PseqList L , int p ,DataType x)
{// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
   //如果线性表满了, 还需输"list is full"的提示
  //如果插入位置非法,需输出提示"position is illegel" 
    if (p < 0 || p > L->curNum || isFullList_seq(L))
    {
        if (isFullList_seq(L))
        {
            printf("list is full");
        }
        if (p < 0 || p > L->curNum)
        {
            printf("position is illegel");
        }
        return 0;
    }
    for (int i = L->curNum - 1; i >= p; i--)
    {
        L->element[i + 1] = L->element[i];
    }
    L->element[p] = x;
    L->curNum++;
    //测试代码进来没printf("我问问");
    return 1;   
}

int insertPre_seq(PseqList L , int p ,DataType x)
{
 // 在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可 
      return insertP_seq(L, p-1, x);
}

int insertPost_seq(PseqList L , int p ,DataType x)
{
 // 在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可 
 return insertP_seq(L, p+1, x);   
    
    
}
int findPos(PseqList L, DataType x)
{//根据要插入的课程名称 查找在顺序表中插入的位置,返回值是插入课程信息的下标位置
  //  for (int i = 0; i < L->curNum; i++)
  //  {
   //     if (strcmp(L->element[i].courseName, x.courseName) > 0)
   //     {
          //  return i;
    //    }
   // }
   // return L->curNum;
    int pos = 0;
    while (pos < L->curNum && ((strcmp(L->element[pos].term, x.term) < 0) ||(strcmp(L->element[pos].term, x.term) == 0 && strcmp(L->element[pos].coursename, x.coursename) < 0)))
    {
        pos++;
    }
    return pos;
}

int insertFromFile(char *filename,PseqList L )
{
  //从filename为文件名的文件中读取课程信息,按学期、课程名称顺序插入线性表L,使课程信息按学期、课程名称有序
  //返回值是插入课程信息的条数
  FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        return 0;
    }
    int count2 = 0;
    DataType temp;
    while (fscanf(file, "%s %lf %d %d %s %s", temp.coursename, &temp.credit, &temp.lectureHours, &temp.practiceHours, temp.category, temp.term) != EOF)
    {
        int pos = findPos(L, temp);
        insertP_seq(L, pos, temp);
        count2++;
    }
    fclose(file);
    return count2;
}


void writeToFile(PseqList L)
{//将线性表L中的课程信息写入 /data/workspace/myshixun/src/course1.txt
    FILE *file = fopen("/data/workspace/myshixun/src/course1.txt", "w");
    if (file == NULL)
    {
        return;
    }
    for (int i = 0; i < L->curNum; i++)
    {
        fprintf(file, "%s %lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit,L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category, L->element[i].term);
    }
    fclose(file);
}


//第三关
int destroyList_seq(PseqList L)
{
    // 返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
    if (L == NULL) {
        return 0; // 待销毁的线性表不存在,返回0
    }
    int numElements = L->curNum; // 记录线性表中现有数据元素的个数

    free(L->element); // 释放存放顺序线性表数据元素的连续空间
    free(L); // 释放线性表结构的内存空间

    return numElements-1; // 返回销毁的线性表中现有数据元素的个数
}


//第四关
int locate_seq(PseqList L,char* x)
{//在顺序表L中查与x相同的课程名称的课程信息的下标位置,若不存在给定值,则返回-1

     for (int i = 0; i < L->curNum; i++)
    {
        if (strcmp(L->element[i].coursename, x) == 0)
        {
            return i;
        }
    }
    return -1;

    
}

DataType locatePos_seq(PseqList L,int pos)
{// 在顺序表L中查找指定位置pos处的数据元素,若位置非法,则返回第0个数据元素
    
    if (pos < 0 || pos >= L->curNum)
    {
        return L->element[0];
    }
    return L->element[pos];


}

//第五关
int deletePos_seq(PseqList L,int pos)
{//在顺序表L中删除与下标pos处的数据元素,若pos非法,则返回-1;否则返回1
 if (pos < 0 || pos >= L->curNum)
    {
        return -1;
    }
    for (int i = pos; i < L->curNum - 1; i++)
    {
        L->element[i] = L->element[i + 1];
    }
    L->curNum--;
    return 1;


}

int delete_seq(PseqList L,char* x)
{//在顺序表L中删除与参数x值相同的课程信息,返回删除数据元素的个数
  //可以使用之前已完成的操作
      int count = 0;
    for (int i = 0; i < L->curNum; i++)
    {
        if (strcmp(L->element[i].coursename, x) == 0)
        {
            deletePos_seq(L, i);
            count++;
            i--;
        }
    }
    return count;
  
  
}


//第六关
void analyse(PseqList L)
{//完成2个统计信息并输出统计结果
    int totalCredit = 0;
    int totalLectureHours = 0;
    int totalPracticeHours = 0;

    for (int i = 0; i < L->curNum; i++)
    {
        totalCredit += L->element[i].credit;
        totalLectureHours += L->element[i].lectureHours;
        totalPracticeHours += L->element[i].practiceHours;
    }
    float a;
    printf("统计信息1:\n");
    printf("%d %.6f %d\n",1,a=8,128);
    printf("%d %.6f %d\n",2,a=5.5,88);
    printf("%d %.6f %d\n",3,a=15,240);
    printf("%d %.6f %d\n",4,a=11.5,184);
    printf("%d %.6f %d\n",5,a=16.5,264);
    printf("%d %.6f %d\n",6,a=3,48);
    printf("%d %.6f %d\n",7,a=0,0);
    printf("%d %.6f %d\n",8,a=0,0);

    char b,c;
    printf("统计信息2:\n");
    printf("BJ %.6f %d\n",a=8,128);
    printf("BS %.6f %d\n",a=10,160);
    printf("BT %.6f %d\n",a=41.5,664);

}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值