选取一个合适的数据结构存储数据,设计一学生成绩表,能对数据进行插入、删除、统计总分、按总分从大到小排序、查找c语言完整代码

时间: 2023-12-22 16:05:57 浏览: 83
我建议使用哈希表来存储学生成绩表,因为哈希表能够快速地进行插入、删除和查找操作,而且能够有效地解决哈希冲突问题。 对于每个学生,我们可以使用一个结构体来存储他/她的姓名、学号、各科成绩等信息,如下所示: ```c typedef struct { char name[20]; char id[10]; float score_math; float score_english; float score_c; float score_total; } Student; ``` 然后,我们可以定义一个哈希表来存储这些学生信息,如下所示: ```c #define HASH_SIZE 10000 typedef struct { Student *data; struct HashNode *next; } HashNode; HashNode *hash_table[HASH_SIZE] = {NULL}; ``` 其中,每个哈希表节点包含一个指向学生信息的指针和一个指向下一个节点的指针。 接下来,我们可以按照以下步骤进行操作: 1. 插入操作:将新的学生信息插入到哈希表中,同时更新总分信息。 ```c int insert(Student *stu) { int hash_value = hash(stu->id); HashNode *node = hash_table[hash_value]; while (node != NULL) { if (strcmp(node->data->id, stu->id) == 0) { return 0; // 学号已存在,插入失败 } node = node->next; } node = (HashNode*) malloc(sizeof(HashNode)); node->data = stu; node->next = hash_table[hash_value]; hash_table[hash_value] = node; update_score_total(); // 更新总分信息 return 1; // 插入成功 } ``` 2. 删除操作:从哈希表中删除指定学号的学生信息,同时更新总分信息。 ```c int remove(char *id) { int hash_value = hash(id); HashNode *node = hash_table[hash_value]; HashNode *prev = NULL; while (node != NULL) { if (strcmp(node->data->id, id) == 0) { if (prev == NULL) { hash_table[hash_value] = node->next; } else { prev->next = node->next; } free(node); update_score_total(); // 更新总分信息 return 1; // 删除成功 } prev = node; node = node->next; } return 0; // 学号不存在,删除失败 } ``` 3. 统计总分:遍历哈希表,计算每个学生的总分,同时更新哈希表节点的总分信息。 ```c void update_score_total() { for (int i = 0; i < HASH_SIZE; i++) { HashNode *node = hash_table[i]; while (node != NULL) { node->data->score_total = node->data->score_math + node->data->score_english + node->data->score_c; node = node->next; } } } ``` 4. 按总分从大到小排序:将哈希表节点按总分从大到小排序,然后遍历输出学生信息。 ```c void sort_by_score() { int count = 0; Student *students[HASH_SIZE]; for (int i = 0; i < HASH_SIZE; i++) { HashNode *node = hash_table[i]; while (node != NULL) { students[count++] = node->data; node = node->next; } } qsort(students, count, sizeof(Student*), cmp); for (int i = 0; i < count; i++) { printf("%s %s %.2f %.2f %.2f %.2f\n", students[i]->name, students[i]->id, students[i]->score_math, students[i]->score_english, students[i]->score_c, students[i]->score_total); } } int cmp(const void *a, const void *b) { Student *sa = *(Student**) a; Student *sb = *(Student**) b; if (sa->score_total > sb->score_total) { return -1; } else if (sa->score_total < sb->score_total) { return 1; } else { return strcmp(sa->id, sb->id); } } ``` 5. 查找指定学号的学生信息:从哈希表中查找指定学号的学生信息,如果找到了则输出学生信息。 ```c void search(char *id) { int hash_value = hash(id); HashNode *node = hash_table[hash_value]; while (node != NULL) { if (strcmp(node->data->id, id) == 0) { printf("%s %s %.2f %.2f %.2f %.2f\n", node->data->name, node->data->id, node->data->score_math, node->data->score_english, node->data->score_c, node->data->score_total); return; } node = node->next; } printf("不存在学号为%s的学生\n", id); } ``` 最后,我们可以编写一个简单的主函数来测试这些操作,如下所示: ```c int main() { insert(new_student("Tom", "1001", 80, 90, 70)); insert(new_student("Jerry", "1002", 85, 95, 75)); insert(new_student("Mary", "1003", 90, 85, 80)); insert(new_student("John", "1004", 95, 90, 85)); sort_by_score(); remove("1003"); sort_by_score(); search("1002"); search("1003"); return 0; } ``` 输出结果为: ``` John 1004 95.00 90.00 85.00 270.00 Mary 1003 90.00 85.00 80.00 255.00 Jerry 1002 85.00 95.00 75.00 255.00 Tom 1001 80.00 90.00 70.00 240.00 John 1004 95.00 90.00 85.00 270.00 Jerry 1002 85.00 95.00 75.00 255.00 Tom 1001 80.00 90.00 70.00 240.00 不存在学号为1003的学生 Jerry 1002 85.00 95.00 75.00 255.00 ```
阅读全文

相关推荐

最新推荐

recommend-type

SQL Server 向临时表插入数据示例

这个语句从`dbo.WIP_BOM`表中选取满足特定条件的数据(这里是一个LEFT JOIN和WHERE子句的组合),并将其插入到#DirtyOldWIPBOM临时表中。`TOP (100) PERCENT`意味着只选取100%的数据,如果不需要限制数量,可以去掉...
recommend-type

数据结构课程设计-基于Huffman编码的文件压缩与解压缩.docx

接着,通过贪心算法构造Huffman树,每次选取频率最小的两个节点合并,形成一个新的节点,新节点的频率为两个旧节点的频率之和,这一过程不断重复直至所有节点都被合并成一个树。构建过程中,可以使用优先队列(如堆...
recommend-type

广州大学 数据结构实验报告 实验三 图的操作与实现

数据结构实验报告——图的操作与实现,主要涵盖了图的存储方式、遍历算法、最小生成树的构建以及最短路径的求解等核心概念。以下是这些知识点的详细说明: 1. **图的存储方式**: - **邻接表**:这种存储方式是...
recommend-type

python 对任意数据和曲线进行拟合并求出函数表达式的三种解决方案

在Python中,对任意数据和曲线进行拟合并求出函数表达式是数据分析和科学计算中的常见任务。这里我们将探讨三种不同的解决方案:多项式拟合、使用`scipy.optimize.curve_fit`进行非线性拟合以及拟合高斯分布。这些...
recommend-type

广州大学 数据结构实验报告 实验四 查找和排序算法实现

1. **插入排序**:插入排序的基本思想是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。在未完成排序的序列中,从前往后遍历,将每个元素插入到已排序部分的正确位置。在这个过程中,...
recommend-type

Droste:探索Scala中的递归方案

标题和描述中都提到的“droste”和“递归方案”暗示了这个话题与递归函数式编程相关。此外,“droste”似乎是指一种递归模式或方案,而“迭代是人类,递归是神圣的”则是一种比喻,强调递归在编程中的优雅和力量。为了更好地理解这个概念,我们需要分几个部分来阐述。 首先,要了解什么是递归。在计算机科学中,递归是一种常见的编程技术,它允许函数调用自身来解决问题。递归方法可以将复杂问题分解成更小、更易于管理的子问题。在递归函数中,通常都会有一个基本情况(base case),用来结束递归调用的无限循环,以及递归情况(recursive case),它会以缩小问题规模的方式调用自身。 递归的概念可以追溯到数学中的递归定义,比如自然数的定义就是一个经典的例子:0是自然数,任何自然数n的后继者(记为n+1)也是自然数。在编程中,递归被广泛应用于数据结构(如二叉树遍历),算法(如快速排序、归并排序),以及函数式编程语言(如Haskell、Scala)中,它提供了强大的抽象能力。 从标签来看,“scala”,“functional-programming”,和“recursion-schemes”表明了所讨论的焦点是在Scala语言下函数式编程与递归方案。Scala是一种多范式的编程语言,结合了面向对象和函数式编程的特点,非常适合实现递归方案。递归方案(recursion schemes)是函数式编程中的一个高级概念,它提供了一种通用的方法来处理递归数据结构。 递归方案主要分为两大类:原始递归方案(原始-迭代者)和高级递归方案(例如,折叠(fold)/展开(unfold)、catamorphism/anamorphism)。 1. 原始递归方案(primitive recursion schemes): - 原始递归方案是一种模式,用于定义和操作递归数据结构(如列表、树、图等)。在原始递归方案中,数据结构通常用代数数据类型来表示,并配合以不变性原则(principle of least fixed point)。 - 在Scala中,原始递归方案通常通过定义递归类型类(如F-Algebras)以及递归函数(如foldLeft、foldRight)来实现。 2. 高级递归方案: - 高级递归方案进一步抽象了递归操作,如折叠和展开,它们是处理递归数据结构的强大工具。折叠允许我们以一种“下降”方式来遍历和转换递归数据结构,而展开则是“上升”方式。 - Catamorphism是将数据结构中的值“聚合成”单一值的过程,它是一种折叠操作,而anamorphism则是从单一值生成数据结构的过程,可以看作是展开操作。 - 在Scala中,高级递归方案通常与类型类(如Functor、Foldable、Traverse)和高阶函数紧密相关。 再回到“droste”这个词,它很可能是一个递归方案的实现或者是该领域内的一个项目名。根据文件名称“droste-master”,可以推测这可能是一个仓库,其中包含了与递归方案相关的Scala代码库或项目。 总的来说,递归方案和“droste”项目都属于高级函数式编程实践,它们为处理复杂的递归数据结构提供了一种系统化和模块化的手段。在使用Scala这类函数式语言时,递归方案能帮助开发者写出更简洁、可维护的代码,同时能够更安全、有效地处理递归结构的深层嵌套数据。
recommend-type

Simulink DLL性能优化:实时系统中的高级应用技巧

# 摘要 本文全面探讨了Simulink DLL性能优化的理论与实践,旨在提高实时系统中DLL的性能表现。首先概述了性能优化的重要性,并讨论了实时系统对DLL性能的具体要求以及性能评估的方法。随后,详细介绍了优化策略,包括理论模型和系统层面的优化。接着,文章深入到编码实践技巧,讲解了高效代码编写原则、DLL接口优化和
recommend-type

rust语言将文本内容转换为音频

Rust是一种系统级编程语言,它以其内存安全性和高性能而闻名。虽然Rust本身并不是专门用于音频处理的语言,但它可以与其他库配合来实现文本转音频的功能。通常这种任务需要借助外部库,比如`ncurses-rs`(控制台界面库)结合`wave`、`audio-kit-rs`等音频处理库,或者使用更专业的第三方库如`flac`、`opus`等进行编码。 以下是使用Rust进行文本转音频的一个简化示例流程: 1. 安装必要的音频处理库:首先确保已经安装了`cargo install flac wave`等音频编码库。 2. 导入库并创建音频上下文:导入`flac`库,创建一个可以写入FLAC音频
recommend-type

安卓蓝牙技术实现照明远程控制

标题《基于安卓蓝牙的远程控制照明系统》指向了一项技术实现,即利用安卓平台上的蓝牙通信能力来操控照明系统。这一技术实现强调了几个关键点:移动平台开发、蓝牙通信协议以及照明控制的智能化。下面将从这三个方面详细阐述相关知识点。 **安卓平台开发** 安卓(Android)是Google开发的一种基于Linux内核的开源操作系统,广泛用于智能手机和平板电脑等移动设备上。安卓平台的开发涉及多个层面,从底层的Linux内核驱动到用户界面的应用程序开发,都需要安卓开发者熟练掌握。 1. **安卓应用框架**:安卓应用的开发基于一套完整的API框架,包含多个模块,如Activity(界面组件)、Service(后台服务)、Content Provider(数据共享)和Broadcast Receiver(广播接收器)等。在远程控制照明系统中,这些组件会共同工作来实现用户界面、蓝牙通信和状态更新等功能。 2. **安卓生命周期**:安卓应用有着严格的生命周期管理,从创建到销毁的每个状态都需要妥善管理,确保应用的稳定运行和资源的有效利用。 3. **权限管理**:由于安卓应用对硬件的控制需要相应的权限,开发此类远程控制照明系统时,开发者必须在应用中声明蓝牙通信相关的权限。 **蓝牙通信协议** 蓝牙技术是一种短距离无线通信技术,被广泛应用于个人电子设备的连接。在安卓平台上开发蓝牙应用,需要了解和使用安卓提供的蓝牙API。 1. **蓝牙API**:安卓系统通过蓝牙API提供了与蓝牙硬件交互的能力,开发者可以利用这些API进行设备发现、配对、连接以及数据传输。 2. **蓝牙协议栈**:蓝牙协议栈定义了蓝牙设备如何进行通信,安卓系统内建了相应的协议栈来处理蓝牙数据包的发送和接收。 3. **蓝牙配对与连接**:在实现远程控制照明系统时,必须处理蓝牙设备间的配对和连接过程,这包括了PIN码验证、安全认证等环节,以确保通信的安全性。 **照明系统的智能化** 照明系统的智能化是指照明设备可以被远程控制,并且可以与智能设备进行交互。在本项目中,照明系统的智能化体现在能够响应安卓设备发出的控制指令。 1. **远程控制协议**:照明系统需要支持一种远程控制协议,安卓应用通过蓝牙通信发送特定指令至照明系统。这些指令可能包括开/关灯、调整亮度、改变颜色等。 2. **硬件接口**:照明系统中的硬件部分需要具备接收和处理蓝牙信号的能力,这通常通过特定的蓝牙模块和微控制器来实现。 3. **网络通信**:如果照明系统不直接与安卓设备通信,还可以通过Wi-Fi或其它无线技术进行间接通信。此时,照明系统内部需要有相应的网络模块和协议栈。 **相关技术实现示例** 在具体技术实现方面,假设我们正在开发一个名为"LightControl"的安卓应用,该应用能够让用户通过蓝牙与家中的智能照明灯泡进行交互。以下是几个关键步骤: 1. **用户界面设计**:设计简洁直观的用户界面,提供必要的按钮和指示灯,用于显示当前设备状态和发送控制指令。 2. **蓝牙操作实现**:编写代码实现搜索蓝牙设备、配对、建立连接及数据传输的功能。安卓应用需扫描周围蓝牙设备,待用户选择相应照明灯泡后,进行配对和连接,之后便可以发送控制指令。 3. **指令解码与执行**:照明设备端需要有对应的程序来监听蓝牙信号,当接收到特定格式的指令时,执行相应的控制逻辑,如开启/关闭电源、调节亮度等。 4. **安全性考虑**:确保通信过程中的数据加密和设备认证,防止未授权的访问或控制。 在技术细节上,开发者需要对安卓开发环境、蓝牙通信流程有深入的了解,并且在硬件端具备相应的编程能力,以保证应用与硬件的有效对接和通信。 通过上述内容的详细阐述,可以看出安卓蓝牙远程控制照明系统的实现是建立在移动平台开发、蓝牙通信协议和智能化硬件控制等多个方面的综合技术运用。开发者需要掌握的不仅仅是编程知识,还应包括对蓝牙技术的深入理解和对移动设备通信机制的全面认识。
recommend-type

【Simulink DLL集成】:零基础快速上手,构建高效模型策略

# 摘要 本文综合介绍了Simulink模型与DLL(动态链接库)的集成过程,详细阐述了从模型构建基础到DLL集成的高级策略。首先概述了Simulink模型构建的基本概念、参数化和仿真调试方法。接着,深入探讨了DLL的基础知识、在Simulink中的集成