用C语言进行学生成绩排序(简单选择排序和对堆排序)

news2024/11/24 11:51:38

一.选择排序

选择排序的基本思想是:每一趟(如第i趟)在后面n-i+1 (i=1,2…,n-1) 个待排序元素中选取关键字最小的元素,作为有序子序列的第i个元素,直到第n-1趟做完,待排序元素只剩下1个,就不用再选了。选择排序中的堆排序算法是历年考查的重点。

二.简单选择排序

1.算法思想

根据上面选择排序的思想,可以很直观地得出简单选择排序算法的思想:假设排序表为[L…n],第i趟排序即从Li.n]中选择关键字最小的元素与I(i)交换,每-趟排序可以确定一个元素的最终位置,这样经过n-1趟排序就可使得整个排序表有序。

2.算法实现

//简单选择排序
void selectsort(SqList &L){
	for(int i=0;i<L.length-1;i++){      //一共进行n-1趟
		Elemtype min=L.data[i];        //记录最小的元素位置
		int n=0;
		for(int j=i+1;j<L.length;j++){  //从未排序部分开始遍历
			if(L.data[j].grade<min.grade) {
				min=L.data[j];
				n=j;
			}
		}
		if(min.grade!=L.data[i].grade){
			Elemtype temp=L.data[i];
			L.data[i]=L.data[n];
			L.data[n]=temp;
		}
	}
}

3.效率分析

简单选择排序算法的性能分析如下:

  • 空间效率:仅使用常数个辅助单元,故空间效率为0(1)。,
  • 时间效率:从上述伪码中不难看出,在简单选择排序过程中,元素移动的操作次数很少,不会超过3(n- 1)次,最好的情况是移动0次,此时对应的表已经有序;但元素间比较的次数与序列的初始状态无关,始终是n(n- 1)/2次,因此时间复杂度始终是0(n2 )。
  • 稳定性:在第i趟找到最小元素后,和第i个元素交换,可能会导致第i个元素与其含有相同关键字元素的相对位置发生改变。例如,表L= {2,2,1},经过一趟排序后L={1,2,2},最终排序序列也是L={1,2,2},显然,2与2的相对次序已发生变化。因此,简单选择排序是一种不稳定的排序方法。

三.堆排序

1.算法思想

堆排序的思路很简单:首先将存放在L1…n]中的n个元素建成初始堆,由于堆本身的特点(以大顶堆为例),堆顶元素就是最大值。输出堆顶元素后,通常将堆底元素送入堆顶,此时根结点已不满足大顶堆的性质,堆被破坏,将堆顶元素向下调整使其继续保持大顶堆的性质,再输出堆顶元素。如此重复,直到堆中仅剩-一个元素为止。可见堆排序需要解决两个问题:①如何将无序序列构造成初始堆?②输出堆顶元素后,如何将剩余元素调整成新的堆?

堆排序的关键是构造初始堆。n个结点的完全二二叉树,最后一个结点是第Ln/2」个结点的孩子。对第Ln/2」个结点为根的子树筛选(对于大根堆,若根结点的关键字小于左右孩子中关键字较大者,则交换),使该子树成为堆。之后向前依次对各结点(Ln/2J-1~1)为根的子树进行筛选,看该结点值是否大于其左右子结点的值,若不大于,则将左右子结点中的较大值与之交换,交换后可能会破坏下一级的堆,于是继续采用上述方法构造下一-级的堆,直到以该结点为根的子树构成堆为止。反复利用上述调整堆的方法建堆,直到根结点。

2.调整示例

初始时调整L(4)子树,09 < 32,交换,交换后满足堆的定义;向前继续调整L(3)子树,78<左右孩子的较大者87,交换,交换后满足堆的定义;向前调整L(2)子树,17 <左右孩子的较大者45,交换后满足堆的定义;向前调整至根结点L(1),53 <左右孩子的较大者87,交换,交换后破坏了L(3)子树的堆,采用上述方法对L(3)进行调整,53<左右孩子的较大者78,交换,至此该完全二叉树满足堆的定义。

在这里插入图片描述

3.C语言实现

void Heapsort(SqList &L){
	buildMaxheap(L);
	for(int i=L.length-1;i>0;i--){
		Elemtype temp=L.data[i];
		L.data[i]=L.data[0];
		L.data[0]=temp;
		HeadAdjust(L,0, i);
	}
}

4.效率分析

堆排序算法的性能分析如下:

  • 空间效率:仅使用了常数个辅助单元,所以空间复杂度为0(1)。
  • 时间效率:建堆时间为O(n),之后有n-1次向下调整操作,每次调整的时间复杂度为O(h),故在最好、最坏和平均情况下,堆排序的时间复杂度为O(nlog2n)。
  • 稳定性:进行筛选时,有可能把后面相同关键字的元素调整到前面,所以堆排序算法是一种不稳定的排序方法。例如,表L= {1, 2, 2},构造初始堆时可能将2交换到堆顶,此时L= {2, 1,2},最终排序序列为L={1,2,2},显然,2与2的相对次序已发生变化。

四.C语言实现完整示例

/*我们今天的主角插入排序是基于查找算法来的,所以我们还是利用线性表来进行模拟*/

/*为了便于我们后面演示希尔排序,所以我们采用顺序存储结构*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MaxSize 50                //这里只是演示,我们假设这里最多存五十个学生信息

//定义学生结构
typedef struct {
	char name[200];              //姓名
	int  grade;               //分数,这个是排序关键字
} Elemtype;

//声明使用顺序表
typedef struct {
	/*这里给数据分配内存,可以有静态和动态两种方式,这里采用动态分配*/
	Elemtype  *data;            //存放线性表中的元素是Elemtype所指代的学生结构体
	int length;                 //存放线性表的长度
} SqList;						//给这个顺序表起个名字,接下来给这个结构体定义方法

//初始化线性表
void InitList(SqList &L){
	/*动态分配内存的初始化*/
	L.data = (Elemtype*)malloc(MaxSize * sizeof(Elemtype));  //为顺序表分配空间
	L.length = 0;                                            //初始化长度为0
}

//求表长函数
int Length(SqList &L){
	return L.length;
}

//求某个数据元素值
bool GetElem(SqList &L, int i, Elemtype &e) {
	if (i < 1 || i > L.length)
		return false;         //参数i错误时,返回false
	e = L.data[i - 1];      //取元素值
	return true;
}

//输出线性表
void DispList(SqList &L) {
	if (L.length == 0)
		printf("线性表为空");
	//扫描顺序表,输出各元素
	for (int i = 0; i < L.length; i++) {
		printf("%s        %d", L.data[i].name,  L.data[i].grade);
		printf("\n");
	}
	printf("\n");
}

//插入数据元素
bool ListInsert(SqList &L, int i, Elemtype e) {
	/*在顺序表L的第i个位置上插入新元素e*/
	int j;
	//参数i不正确时,返回false
	if (i < 1 || i > L.length + 1 || L.length == MaxSize)
		return false;
	i--;                //将顺序表逻辑序号转化为物理序号
	//参数i正确时,将data[i]及后面的元素后移一个位置
	for (j = L.length; j > i; j--) {
		L.data[j] = L.data[j - 1];
	}
	L.data[i] = e;      //插入元素e
	L.length++;         //顺序表长度加1
	return true;
	/*平均时间复杂度为O(n)*/
}

//简单选择排序
void selectsort(SqList &L){
	for(int i=0;i<L.length-1;i++){      //一共进行n-1趟
		Elemtype min=L.data[i];        //记录最小的元素位置
		int n=0;
		for(int j=i+1;j<L.length;j++){  //从未排序部分开始遍历
			if(L.data[j].grade<min.grade) {
				min=L.data[j];
				n=j;
			}
		}
		if(min.grade!=L.data[i].grade){
			Elemtype temp=L.data[i];
			L.data[i]=L.data[n];
			L.data[n]=temp;
		}
	}
}

void HeadAdjust(SqList &L,int k, int len){
	Elemtype temp=L.data[k];
	for(int i=2*k+1;i<len;i=2*i+1){
		if(i<len-1 && L.data[i].grade<L.data[i+1].grade)
			i++;
		if(temp.grade>=L.data[i].grade)
			break;
		else{
			L.data[k]=L.data[i];
			k=i;
		}
	}
	L.data[k]=temp;
}

void buildMaxheap(SqList &L){
	for(int i=L.length/2-1;i>=0;i--)
		HeadAdjust(L, i, L.length);
}

void Heapsort(SqList &L){
	buildMaxheap(L);
	for(int i=L.length-1;i>0;i--){
		Elemtype temp=L.data[i];
		L.data[i]=L.data[0];
		L.data[0]=temp;
		HeadAdjust(L,0, i);
	}
}

int main(){
	SqList L;
	Elemtype stuents[10]={{"张三",649},{"李四",638},{"王五",665},{"赵六",697},{"冯七",676},
		{"读者",713},{"阿强",627},{"杨曦",649},{"老六",655},{"阿黄",604}};
	//这一部分忘了的请回顾我的相关博客
	printf("初始化顺序表并插入开始元素:\n");
	InitList(L);         //这时是一个空表,接下来通过插入元素函数完成初始化
	for (int i = 0; i < 10; i++)
		ListInsert(L, i + 1, stuents[i]);
	DispList(L);
	/*printf("根据分数进行简单选择排序后结果为:\n");
	selectsort(L);
	DispList(L);          //到这一步我们的简单选择排序没什么问题的
	 */
	printf("根据分数进行堆排序后结果为:\n");
	Heapsort(L);
	DispList(L);
}

五.运行结果

1.简单选择排序

在这里插入图片描述

2.堆排序

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/744149.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDEA配置Maven教程

IDEA配置Maven教程 &#x1f495;1、mavne的下载&#x1f495;2、maven的安装&#x1f49e;3、配置Maven环境变量&#x1f49e;4、配置 Maven 本地仓库存放路径&#x1f496; 5、settings.xml配置&#xff1b;&#x1f496;6、IDEA配置maven&#xff1b;&#x1f496;7、清理下…

不容小觑:MES系统上线后绝对不能大意的几点

随着工业自动化和信息化的普及&#xff0c;制造执行系统&#xff08;MES&#xff09;已经成为现代制造企业的重要组成部分。然而&#xff0c;即使在实施MES系统之后&#xff0c;企业仍然不能掉以轻心。本文将探讨MES系统上线后需要引起注意的几个方面&#xff0c;以帮助企业更好…

SolidWorks如何切换语言选项

一些工程师的电脑上安装的上英文操作系统&#xff0c;这种操作系统如果安SolidWorks的话&#xff0c;即已经安装上中文语言包&#xff0c;但打开SolidWorks后&#xff0c;其界面还是英文界面。如何在英文Windows操作系统中运行中文版的SolidWorks呢&#xff1f; 照成以上问题可…

Maven下载和配置教程:Windows、Mac和Linux系统安装指南

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

JDBC技术概述

1.1 JDBC技术概述 Java Database Connectivity 简称JDBC&#xff0c;是Java数据库连接的技术。是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口&#xff0c;提供了诸如查询和更新数据库中数据的方法。 JDBC是Java访问数据库的标准规则&#xff0c;可以为不同的…

数据结构与算法——时间复杂度和空间复杂度(详解版)

在学习具体的数据结构和算法之前&#xff0c;每一位初学者都要掌握一个技能&#xff0c;即善于运用时间复杂度和空间复杂度来衡量一个算法的运行效率。 所谓算法&#xff0c;即解决问题的方法。同一个问题&#xff0c;使用不同的算法&#xff0c;虽然得到的结果相同&#xff0…

记一次 频繁Full GC JVM调优

记一次 频繁Full GC JVM调优 背景 观察服务监控平台的时候发现&#xff0c;几乎 20分钟就会触发一次 Full GC&#xff1b; 问题定位 因为对我们系统JVM参数都很熟悉&#xff0c;所以问题定位很快&#xff0c;通过监控就定位到 每次触发FullGC 的时间 都与MetaSapceSize达到…

Elasticsearch原理剖析

一、 Elasticsearch结构 Elasticsearch集群方案由EsMaster、EsClient和EsNode1、EsNode2、EsNode3、EsNode4、EsNode5、EsNode6、EsNode7、EsNode8、EsNode9进程组成&#xff0c;如下图所示&#xff0c;模块说明如表下所示。 说明如表&#xff1a; 名称说明ClientClient使用H…

统计连续字符-2022年全国青少年信息素养大赛Python国赛第7题

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛真题系列的第9讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设计…

2.1 线性表的逻辑结构与存储结构

在之前的数据结构知识铺垫2&#xff1a;物理结构与逻辑结构一文中, 我们介绍了物理结构与逻辑结构, 物理结构即存储结构. 本篇文章我们着重探讨一下线性表的逻辑结构与存储结构. 1. 线性表的逻辑结构 图1. 线性表的逻辑结构 线性表是具有相同特性的数据元素的有限序列, 每个元…

SHELL CLASH配置规则

本地环境 小米AX1800路由器&#xff0c;旧版&#xff08;黢黑的四方立柱体&#xff0c;没有天线&#xff09;&#xff0c;已降级至固定版本小米 AX1800 1.0.336 问题 因为某些网络原因&#xff0c;在WiFi中安装了shell clash作为互联网代理&#xff0c;使用部分软件时提示网…

ChatGPT在大学里该怎么用?24所英国顶级大学宣布立场!

自从ChatGPT横空出世以来&#xff0c;许多行业都被得到赋能。而在教育行业&#xff0c;许多大学生把它视为写作业的“神器”&#xff1a;节省查阅复杂文献的时间、编写简单的Python代码、辅助学生理解知识点&#xff0c;甚至直接“生成”论文...... 但这些行为&#xff0c;学校…

个人使用:Windows下 OpenCV 的下载安装(2021.12.4详细)

一、下载OpenCV   到OpenCV官网Release(发布)板块下载OpenCV-4.5.4 Windows。 下载后是这样的 然后双击他&#xff0c;解压&#xff0c;就是大佬们说的安装&#xff0c;实质就是解压一下&#xff0c;解压完出来一个文件夹&#xff0c;其他什么也没发生。你把这个文件夹放在哪…

4、Kubernetes 架构、理解 k8s 架构

kubeadm 用于初始化 Cluster。 kubectl 是 Kubernetes 命令行工具。通过 kubectl 可以部署和管理应用,查看各种资源,创建、删除和更新各种组件。 kubelet 运行在 Cluster 所有节点上,负责启动 Pod 和容器。 Kubernetes Cluster 由 Master 和 Node 组成,节点上运行着若干 Ku…

【Linux从入门到精通】gdb调式技巧大全

本篇文章会对开发工具:gdb调试器的使用进行讲解。希望本篇文章会对你有所帮助。 目录 一、gdb简单介绍 二、gdb 调试 2、1 加入调试信息 2、2 调试命令 2、2、1 gdb可执行程序——进入调式 2、2、2 l行号/函数名——显示代码 2、2、3 b行号/函数名——打断点 2、2、4 infob——…

mysql数据库的定时备份脚本(docker环境和非docker环境)

一、非docker安装的MySQL MySQL作为一种常用的数据库管理系统,拥有着众多的优秀特性,如高性能、高可靠性、高可扩展性等。然而,在数据备份上,也需要我们进行一定的处理,这样才能保证数据的安全性。因此,在这里我们将介绍如何定时备份MySQL数据库。 我们可以通过MySQL自…

Filebeat+ELK (grok、mutate、mutiline、date)详解

目录 一&#xff1a;FilebeatELK 部署 1&#xff0e;安装 Filebeat 2&#xff0e;设置 filebeat 的主配置文件 3.在 Logstash 组件所在节点上新建一个 Logstash 配置文件 4.访问登录 二&#xff1a;grok 正则捕获插件 1、内置正则表达式调用 2、举例说明 3、自定义表达式…

飞腾开发者平台上线龙蜥专区,为开发者提供硬核技术支持

开源的本质在“人”&#xff0c;开源社区是由一个个做贡献的人构建起来的。近日&#xff0c;飞腾开发者平台联合国内领先的操作系统开源社区——龙蜥社区&#xff0c;推出龙蜥专区&#xff0c;旨在为广大开源爱好者提供社区前沿技术和一线开源文档。 龙蜥专区&#xff08;专区…

从低效率到高效率,开源大数据技术助力职场办公质的飞跃!

在办公流程化管理越来越流行的今天&#xff0c;如何让职场办公实现高效率飞跃和发展&#xff1f;应用开源大数据技术和低代码技术平台&#xff0c;可以实现这一目的&#xff0c;助力企业从传统的开发模式中剥离出来&#xff0c;实现高效率办公发展。今天&#xff0c;趁着大好契…

天池大赛中药说明书实体识别挑战冠军方案开源(一)方案及模型原理说明

目录 Introduction 导言赛题背景任务描述数据探索分析 核心思路数据预处理Baseline: BERT-CRF优化1&#xff1a;对抗训练优化2&#xff1a;混合精度训练&#xff08;FP16&#xff09;优化3&#xff1a;多模型融合优化4&#xff1a;半监督学习其他无明显提升的尝试方案最终线上成…