实验六 排序相关典型算法实现

一 实验目的

1.熟悉并掌握各种排序方法的设计思路。

2.掌握各种具体排序算法在计算机上的实现。

3.掌握各种排序方法的性能比较。

二 实验内容及要求

实验内容

1. 编程实现如下功能:

(1)输入同样一组整型数据,作为待排序记录的关键字序列。

(2)在进行直接插入排序的同时,统计在排序方法中对关键字的比较次数和移动次数,并输出统计结果。

(3)在进行冒泡排序的同时,统计在排序方法中对关键字的比较次数和移动次数,并输出统计结果。

(4)在进行简单选择排序的同时,统计在排序方法中对关键字的比较次数和移动次数,并输出统计结果。

2. 编程实现如下功能之一:

(1)希尔排序

(2)快速排序

(3)堆排序

实验要求:

1.键盘输入数据;

2.屏幕输出运行结果。

3.要求记录实验源代码及运行结果。

4.运行环境:CodeBlocks/Dev c++/VC6.0C编译环境

三 实验方法及运行结果

实验一:完成插入排序,冒泡排序,选择排序的操作,并且统计其移动次数和比较次数。

一 算法设计思路

包括五个功能函数: InputSqlist(Sqlist& l)、InitialSqlist(Sqlist& l)、OutPutSqlist(Sqlist l)、BubbleSort(Sqlist &l)、SelectSort(Sqlist& l)、 InsertSort(Sqlist &l)、和一个主函数

前三个函数分别对应初始化、输入和输出功能。

直接插入排序算法InsertSort(Sqlist &l)的思路:

初始时,将第一个元素视为已排序序列,其余元素为未排序序列。然后,依次将未排序序列中的元素插入到已排序序列的正确位置,直到所有元素都被插入到已排序序列中,完成排序。

首先从第二个元素开始,将其视为当前要插入的元素。接着将当前元素与已排序序列中的元素逐个比较,直到找到插入位置或者已经比较到已排序序列的第一个元素为止。然后在比较的方法中,如果当前元素小于已排序序列中的某个元素,则将该元素后移一位,为当前元素腾出插入位置。将当前元素插入到正确的位置,即将其放置在比它大的元素之前。最后重复上面两步,直到所有元素都被插入到已排序序列中。

冒泡排序算法BubbleSort(Sqlist &l)的思路:

基本思想是通过不断比较相邻元素的大小,将较大的元素逐步交换到右侧,从而实现排序的目的。从序列的第一个元素开始,依次比较相邻的两个元素。如果前一个元素大于后一个元素,则交换它们的位置,将较大的元素往右移动。继续比较下一对相邻元素,重复上一步,直到比较到序列的倒数第二个元素。重复执行执行上述步骤,直到没有需要交换的元素,即序列已经完全排序。

选择排序算法SelectSort(Sqlist& l)的思路:

选择排序是每次从待排序的序列中选择最小(或最大)的元素,放到已排序序列的末尾(或开头),从而逐步形成有序序列。

首先遍历待排序序列,将第一个元素视为当前最小(或最大)元素。然后从剩余未排序的元素中,依次找到最小(或最大)的元素,并记录其位置。接着将找到的最小(或最大)元素与当前最小(或最大)元素进行交换,将最小(或最大)元素放到已排序序列的末尾(或开头)。最后重复上面两步,直到所有元素都被放置到正确的位置上。

选择排序算法不断地选择最小(或最大)元素,并将其放置到已排序序列的末尾(或开头)。这样,每一次选择排序都会确定一个元素的最终位置,直到所有元素都被放置到正确的位置上,完成排序。选择排序每次只需要进行一次交换操作。

二 源程序代码
/*1. 编程实现如下功能:
(1)输入同样一组整型数据,作为待排序记录的关键字序列。
(2)在进行直接插入排序的同时,统计在排序过程中对关键字的比较次数和移动次数,并输出统计结果。
(3)在进行冒泡排序的同时,统计在排序过程中对关键字的比较次数和移动次数,并输出统计结果。
(4)在进行简单选择排序的同时,统计在排序过程中对关键字的比较次数和移动次数,并输出统计结果。
*/
#define MAXSIZE 1000
typedef struct Sqlist
{int Arr[MAXSIZE];int Length;int Comparison;int Move;
};
void InsertSort(Sqlist &l)
{int j=0;//直接排序只有第一个元素有序for ( int i = 2; i <= l.Length; i++)//从2开始排序{l.Comparison+=2;if (l.Arr[i] < l.Arr[i - 1]){l.Arr[0] = l.Arr[i];l.Arr[i] = l.Arr[i - 1];l.Move += 4;for (j = i - 2; l.Arr[0] < l.Arr[j];--j){l.Comparison+=2;l.Arr[j + 1] = l.Arr[j];l.Move+=2;}l.Comparison+=2;//判断跳出循环还有一次l.Arr[j + 1] = l.Arr[0];}l.Move+=2;}
}void InputSqlist(Sqlist& l)
{cout << "请输入要输入的数组的长度" << endl;cin >> l.Length;cout << "请输入数组的数据" << endl;for (int i = 1; i <= l.Length; i++)cin >> l.Arr[i];//此处arr[0]作为哨兵单元不放置元素
}
void InitialSqlist(Sqlist& l)
{for (int i = 0; i < MAXSIZE; i++)l.Arr[i] = 0;l.Length = 0;l.Move = 0;l.Comparison = 0;
}void OutPutSqlist(Sqlist l)
{for (int i = 1; i <= l.Length; i++)cout << l.Arr[i] << " ";cout << "\n此次的比较次数为" << l.Comparison << endl;cout << "此次的移动次数" << l.Move << endl;
}
void BubbleSort(Sqlist &l)
{int max = 0, min = 0; int tem;for (int j = 1; j <=l.Length-1; j++)        //此处循环length-1次 就是数组长度-1次内部操作{for (int i = 2; i <=l.Length-j+1; i++)    //一次内部循环可以将一个数“送”到正确位置{                                //比如第一次内部循环结束后可以让arr[9]变成最大值9max = l.Arr[i - 1];min = l.Arr[i];l.Comparison++;if (min <= max){tem = max;max = min;min = tem;}l.Arr[i - 1] = max;l.Arr[i] = min;l.Move+=3;}}
}
void SelectSort(Sqlist& l)
{for (int i = 1; i < l.Length; i++){int flag = i;int tem; int min = l.Arr[i];for (int j = i+1; j <=l.Length; j++){l.Comparison++;if (min > l.Arr[j]){min = l.Arr[j];flag = j;}}tem = l.Arr[i];l.Arr[i] = min;l.Arr[flag] = tem;l.Move += 3;}
}
int main()
{Sqlist l; int n = 0;InitialSqlist(l);InputSqlist(l);cout << "\n插入排序:" << endl;InsertSort(l);OutPutSqlist(l);InitialSqlist(l);InputSqlist(l);cout << "\n冒泡排序:" << endl;BubbleSort(l);OutPutSqlist(l);InitialSqlist(l);InputSqlist(l);cout << "\n选择排序:" << endl;SelectSort(l);OutPutSqlist(l);return 0;
}

实验二:完成快速排序、堆排序、希尔排序中任意一个(待更新)。

一 算法设计思路

快速排序QuickSort (Sqlist&l, int left, int right)算法思路:

具体的步骤如下:选择一个基准元素(选择第一个)。将序列中的元素分为两部分,小于等于基准元素的放在左边,大于基准元素的放在右边。这个方法称为分区。对左右两个子序列分别进行快速排序,递归地重复上述步骤,直到子序列的长度为1或0,此时子序列已经有序。合并左子序列、基准元素和右子序列,得到最终的有序序列。

二 源程序代码

typedef struct Sqlist
{int Arr[MAXSIZE];int Length;int Comparison;int Move;
};
void InputSqlist(Sqlist& l)
{cout << "请输入要输入的数组的长度" << endl;cin >> l.Length;cout << "请输入数组的数据" << endl;for (int i = 1; i <= l.Length; i++)cin >> l.Arr[i];//此处arr[0]作为哨兵单元不放置元素
}
void InitialSqlist(Sqlist& l)
{for (int i = 0; i < MAXSIZE; i++)l.Arr[i] = 0;l.Length = 0;l.Move = 0;l.Comparison = 0;
}
void OutPutSqlist(Sqlist l)
{for (int i = 1; i <= l.Length; i++)cout << l.Arr[i] << " ";/*cout << "\n此次的比较次数为" << l.Comparison << endl;cout << "此次的移动次数" << l.Move << endl;*/
}void QuickSort(Sqlist&l, int left, int right)
{int i = left - 1, j = right + 1, x = l.Arr[left + right >> 1]; //l代表数组起始端 r代表数组结束if (left >= right) return;//递归结束条件while (i < j){do i++; while (l.Arr[i] < x);  //确保l.Arr[i]全是小于x的do j--; while (l.Arr[j] > x);  //确保l.Arr[j]全是大于x的if (i < j) swap(l.Arr[i], l.Arr[j]); //当停下时 i和j 都不满足 所以交换}QuickSort(l, left, j); QuickSort(l, j + 1, right);// 也可以是 QuickSort(l.Arr,l,i-1);QuickSort(l.Arr,i,r);
// i本身在左边最后一次执行的时候 到区间中点右边 所以更偏左边的是i-1 ,递归区间实现全覆盖但不交叉所以右边是i,r 左边是 l,i-1
// j和j+1同理
}
int main()
{Sqlist l;InitialSqlist(l);InputSqlist(l);QuickSort(l, 1, l.Length);OutPutSqlist(l);
}

四 调试情况、设计技巧及体会

目录

一 实验目的

二 实验内容及要求

实验内容:

1. 编程实现如下功能:

2. 编程实现如下功能之一:

实验要求:

三 实验方法及运行结果

实验一:完成插入排序,冒泡排序,选择排序的操作,并且统计其移动次数和比较次数。

一 算法设计思路

二 源程序代码

实验二:完成快速排序、堆排序、希尔排序中任意一个(待更新)。

一 算法设计思路

二 源程序代码

四 调试情况、设计技巧及体会


在实现本次实验的相关排序算法的实现方法中,以下是我犯的错误以及相应的修改方法以及收获:

1.错误:未正确处理边界条件。

修改方法:在实现插入排序算法时,要确保对数组的索引进行正确的边界检查。例如,循环变量的范围应该是从1到n(数组长度),而不是从0到n-1。此外,还要确保在插入元素时,正确处理数组的边界情况,以避免越界错误。

收获:在编写代码时,始终要注意数组索引的边界情况,并进行适当的边界检查。确保循环变量的范围和条件正确设置,以避免数组越界错误。

2.错误:未正确处理重复元素的情况。

修改方法:在实现插入排序算法时,要考虑重复元素的情况。如果存在重复元素,确保它们被正确地插入到已排序的子数组中,并保持它们的相对顺序。可以通过在插入位置之前或之后进行适当的调整来处理重复元素。

收获:处理重复元素时,要仔细考虑它们的相对顺序,并确保它们被正确地插入到已排序的子数组中。可以使用适当的比较条件和调整方法来处理重复元素,以获得正确的排序结果。

3.错误:未正确统计移动和比较次数。

修改方法:在统计移动和比较次数时,要确保在实际发生移动和比较操作后进行统计。例如,在元素交换或插入位置时,增加相应的计数器。同时,要注意统计的粒度,可以在排序算法的最后输出统计结果,或者在每一次移动或比较操作后即时输出统计结果。

收获:在编写代码时,要注意在正确的位置统计移动和比较次数。确保在实际发生移动和比较操作后进行计数,以获得准确的统计结果。同时,要灵活选择统计的粒度,以适应不同的需求。

4.错误:未正确处理数组为空或只有一个元素的情况。

修改方法:在实现选择排序算法时,要考虑特殊情况,如数组为空或只有一个元素的情况。在这种情况下,数组已经是有序的,无需进行排序操作。可以通过添加条件判断来处理这种情况,直接返回或跳过排序操作。

收获:在编写代码时,要考虑特殊情况,并进行相应的处理。特别是在排序算法中,要注意处理数组为空或只有一个元素的情况,以避免不必要的操作和错误。

在这次实验中我收获了很多,这将未我将来学好算法打下良好的基础,同时我觉得自己还应该继续加深对这些算法的理解,并进行相关的改写来实现一些功能,让他们得到应用。

 

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

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

相关文章

CGAL的手柄和循环器

1、手柄 CGAL中的大多数数据结构在其用户界面中使用Handles 的概念来引用它们存储的元素。这个概念描述了有时被称为琐碎迭代器的东西。Handle类似于指向对象的指针&#xff0c;提供解引用运算符*&#xff08;&#xff09;和成员访问运算符->&#xff08;&#xff09;&#…

【Java代码审计】目录穿越篇

【Java代码审计】目录穿越篇 1.Java中的目录穿越2.目录穿越漏洞审计3.Java中目录穿越漏洞修复 1.Java中的目录穿越 目录穿越漏洞产生的本质是路径可控&#xff0c;一旦涉及文件的读取问题便会涉及java.io.File类&#xff0c;因此在审计这类漏洞时可以优先查找java.io.File引用…

最强Pose模型RTMO开源 | 基于YOLO架构再设计,9MB+9ms性能完爆YOLO-Pose

实时多人在图像中的姿态估计面临着在速度和精度之间实现平衡的重大挑战。尽管两阶段的上下文方法在图像中人数增加时会减慢速度&#xff0c;但现有的单阶段方法往往无法同时实现高精度和实时性能。 本文介绍了RTMO&#xff0c;这是一个单阶段姿态估计框架&#xff0c;通过在YOL…

超文本传送协议HTTP

目录 HTTP简介&#xff1a; URL的格式&#xff1a; HTTP协议的特点&#xff1a; HTTP/1.0协议&#xff1a; HTTP/1.1协议&#xff1a; HTTP/2: HTTP代理服务器&#xff1a; HTTP的报文结构&#xff1a; 请求报文的特点&#xff1a; 响应报文的特点&#xff1a; Cook…

小 cookie,大作用:探索网站中的隐私追踪器(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

大华 DSS 数字监控系统 itcBulletin SQL 注入漏洞复现

0x01 产品简介 大华 DSS 数字监控系统是大华开发的一款安防视频监控系统,拥有实时监视、云台操作、录像回放、报警处理、设备管理等功能。 0x02 漏洞概述 大华 DSS存在SQL注入漏洞,攻击者 /portal/services/itcBulletin 路由发送特殊构造的数据包,利用报错注入获取数据库…

springboot——定时任务、异步任务

springboot——定时任务、异步任务 一、定时任务1、创建一个定时任务、时间配置文件2、springboot主程序开启定时任务 EnableScheduling3、使用 Scheduled 注解 二、定时任务、异步执行。1、springboot主程序开启异步任务 EnableAsync2、方法上增加 Async 注解&#xff0c;标识…

【JAVA日志框架】JUL,JDK原生日志框架详解。

前言 Java日志体系混乱&#xff1f;Java日志框架系列&#xff0c;清晰简洁整理好整个Java的日志框架体系。第一篇&#xff0c;JDK原生日志框架——JUL。 目录 1.概述 2.日志级别 3.配置 4.继承关系 1.概述 日志框架的核心问题&#xff1a; 日志是用来记录应用的一些运行…

.NET基础面试题一

1.C#中堆和栈的区别? 堆(Heap)和栈(Stack)是C#中两种分配内存的不同方式 栈(Stack)&#xff1a;是一种先进后出的内存分配方式。它用于存储基本数据类型和对象引用&#xff0c;它是一种连续的内存空间&#xff0c;存储在cpu的寄存器上&#xff0c;它的大小在编译的时就是已知的…

nodejs+vue+微信小程序+python+PHP校园二手交易系统的设计与实现-计算机毕业设计推荐

(2)管理员 进行维护&#xff0c;以及平台的后台管理工作都依靠管理员&#xff0c;其可以对信息进行管理。需具备功能有&#xff1b;首页、个人中心、学生管理、物品分类管理、物品信息管理、心愿贴、系统管理、订单管理等功能。系统分成管理员控制模块和学生模块。 本系统有良好…

pyansys环境配置(安装所需的库)

目录 1. 环境配置&#xff1a; 2. pyansys库配合Ansys软件启动代码 1. 环境配置&#xff1a; 试了好多种版本&#xff0c;最终以下版本可以跑通&#xff1a; 注意&#xff1a;Python和ANSYS的版本也会影响到安装包的版本&#xff0c;我使用的配置如下&#xff1a; Python3.9…

maven+spock

pom配置 话说JunitMockito的组合用起来是真难用&#xff0c;还是Spock的简单&#xff0c;尤其是参数化的测试。junit的Parameter是鸡肋&#xff0c;杂恶心&#xff1b;Theories用来也不爽。 <?xml version"1.0" encoding"UTF-8"?><project xm…

linux ioctl

ioctl 接口介绍 大部分驱动需要 -- 除了读写设备的能力 -- 通过设备驱动进行各种硬件控制的能力. 大 部分设备可进行超出简单的数据传输之外的操作; 用户空间必须常常能够请求, 例如, 设 备锁上它的门, 弹出它的介质, 报告错误信息, 改变波特率, 或者自我销毁. 这些操作常 常通…

【大数据】Doris 的集群规划和环境准备

Doris 的集群规划和环境准备 1.1 环境要求1.1 Linux 操作系统版本需求1.2 软件需求 1.2 硬件要求1.3 节点规划1.4 通信端口1.5 IP 地址绑定 Doris 作为一款开源的 MPP 架构 OLAP 数据库&#xff0c;能够运行在绝大多数主流的商用服务器上。为了能够充分运用 MPP 架构的并发优势…

Spring容器中scope为prototype类型Bean的回收机制

文章目录 一、背景二、AutowireCapableBeanFactory 方法 autowireBean 分析三、Spring 容器中 scope 为 prototype 类型 Bean 的回收机制四、总结 一、背景 最近做 DDD 实践时&#xff0c;遇到业务对象需要交给 Spring 管理才能做一些职责内事情。假设账号注册邮箱应用层代码流…

Flask学习三:模型操作

ORM flask 通过Model操作数据库&#xff0c;不管你的数据库是MySQL还是Sqlite&#xff0c;flask自动帮你生成相应数据库类型的sql语句&#xff0c;所以不需要关注sql语句和类型&#xff0c;对数据的操作flask帮我们自动完成&#xff0c;只需要会写Model就可以了 flask使用对象关…

第十五章总结

一.输入/输出流 1.输入流 InputStrema类是字节输入流的抽象类&#xff0c;它是所有字节输入流的父类。 该类中所有方法遇到错误都会引发IOException异常。 read()方法&#xff1a;从输入流中读取数据的下一个字节。返回0~255的int字节值。如果因为已经到达流末尾而没有可用的…

vue3通过provide与inject我们可以把父组件数据传递N个层级的子组件

vue3 provide 与 inject 我们通过props属性可以把数据传给组件&#xff0c;而通过provide与inject我们可以把数据传递给N个层级的子组件&#xff0c;比如A组件用了B组件&#xff0c;B组件用了C组件&#xff0c;它可以把组件直接从A传给C组件,vue2使用computed来实现响应式,而v…

【模块化】 js 模块化(CommonJS, AMD, UMD, CMD, ES6)

目录 js 的演变模块化1. CommonJS 规范commonJs伪代码⭐CommonJS优缺点 2. AMD 规范⭐AMD 优缺点 3. UMD 规范⭐UMD AMD CommonJS 4. CMD 规范⭐CMD 优缺点 5. ES6 模块化符号绑定⭐ESM 优缺点 AMD 和 CMD 的区别ES6 模块与 CommonJS 模块的差异参考 将介绍几种 js 模块化的规…

新能源汽车的“一池春水”,或许不再由价格战掀起波澜?

2005年12月15日&#xff0c;丰田普锐斯混合动力车进入中国&#xff0c;拉开了国内新能源汽车发展的序幕。18年后的今天&#xff0c;国产及进口的新能源汽车已经渗透我国超三分之一的乘用车市场&#xff0c;与油车二分天下的愿景渐趋实现。 今年11月&#xff0c;随着购车需求进…