数据结构从入门到精通——排序的概念及运用

news2025/2/25 15:01:38

排序的概念及运用

  • 前言
  • 一、排序的概念
    • 排序
    • 稳定性
    • 内部排序
    • 外部排序
  • 二、排序运用
  • 三、常见的排序算法
  • 四、排序性能检测代码
    • srand()
    • clock()
  • 五、oj排序测试代码


前言

排序是将数据按照一定规则重新排列的过程,常见规则有升序、降序等。排序算法如冒泡排序、快速排序等,广泛用于数据库、搜索引擎等场景,提高数据检索效率。此外,排序也应用于统计分析、机器学习等领域,以获取有序数据集或发现数据间的关联。

排序是一种将一组数据按照一定的规则重新排列的操作。通常,排序的目标是将数据按照某种顺序进行排列,比如按照升序或降序排列。排序算法是对数据进行排序的具体步骤和方法。

排序算法在计算机科学和数据结构中具有广泛的应用。在实际生活中,排序也随处可见。比如在图书馆中,图书按照作者姓名或图书编号进行排序,使得读者能够更方便地查找所需的图书。在金融领域,股票交易价格也需要按照时间顺序进行排序。

排序算法的选择根据数据规模和性质的不同而有所差异。常见的排序算法包括冒泡排序、插入排序、选择排序、快速排序、归并排序等。这些算法在时间复杂度和空间复杂度上有各种差异,因此在实际应用中需要根据具体情况选择适合的算法。

排序算法的效率对于处理大量数据的程序非常重要。在一些场景下,排序算法的效率甚至可以决定整个程序的性能。因此,研究和优化排序算法是计算机科学领域的重要课题之一。


一、排序的概念

排序

排序的概念,简而言之,就是对一组数据元素按照某种特定的顺序进行重新排列的过程。这种顺序可以是升序、降序,或者是根据某种特定的规则进行排序。排序算法是计算机科学中的一个重要分支,广泛应用于数据处理、搜索引擎、数据库管理等领域。

在日常生活和工作中,排序的概念也无处不在。例如,在超市购物时,商品按照价格或类别进行排序,方便顾客快速找到所需商品;在图书馆中,书籍按照书名或作者进行排序,便于读者查找;在学校的成绩管理中,学生的成绩按照分数从高到低或从低到高进行排序,方便教师进行评估和比较。

在计算机科学中,排序算法的种类繁多,各有其优缺点。常见的排序算法有冒泡排序、选择排序、插入排序、归并排序、快速排序等。冒泡排序通过相邻元素之间的比较和交换,逐步将最大的元素“冒”到序列的末尾;选择排序则通过每次选择剩余元素中的最小(或最大)元素,将其放到序列的起始位置;插入排序则是将每个元素插入到已排序的序列中的适当位置,从而保持整个序列的有序性。归并排序和快速排序则采用了分治的思想,将待排序的序列划分为若干个子序列,分别对子序列进行排序,然后将排序结果合并起来,得到最终的有序序列。

不同的排序算法在不同的应用场景下具有不同的性能表现。例如,对于小规模的数据集,冒泡排序和选择排序等简单算法可能更加适用,因为它们的时间复杂度相对较低;而对于大规模的数据集,归并排序和快速排序等高效算法则更具优势,因为它们可以在更短的时间内完成排序任务。

除了算法本身的性能外,排序的效果还受到数据特性、排序规则等多种因素的影响。例如,对于已经部分有序的数据集,插入排序等算法可能具有更好的性能表现;而对于包含大量重复元素的数据集,桶排序等算法则可能更加高效。

总之,排序的概念在日常生活和计算机科学中都具有广泛的应用。通过选择合适的排序算法和考虑各种影响因素,我们可以实现高效、准确的数据排序,为数据分析和处理提供有力支持。同时,对排序算法的研究和改进也是计算机科学领域的一个重要课题,有助于推动相关技术的发展和创新。

稳定性

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

内部排序

数据元素全部放在内存中的排序。

内部排序是数据处理过程中的重要环节,它指的是在没有外部存储设备辅助的情况下,仅依靠计算机的内存对数据进行排序的过程。这一过程对于提高数据处理效率、优化数据结构、以及实现高效算法都至关重要。

内部排序算法的选择依赖于数据的特性,如数据量的大小、数据类型的复杂性以及排序要求的严格程度等。常见的内部排序算法有冒泡排序、插入排序、选择排序、快速排序、归并排序、堆排序等。这些算法各有优缺点,适用于不同的场景。

例如,对于数据量较小的情况,冒泡排序和插入排序等简单算法可能就足够高效;而对于大数据量的处理,快速排序、归并排序等更为复杂的算法则可能更加适合。此外,对于某些特定类型的数据,如已经部分排序的数据或具有特殊分布规律的数据,还可以采用更为高效的特定算法。

在实际应用中,内部排序算法的选择还需要考虑内存使用的效率。因为内部排序完全依赖于内存,如果算法的内存使用效率不高,即使排序速度再快,也可能因为内存占用过多而导致整体性能下降。因此,在实际应用中,我们需要根据具体情况综合考虑算法的时间复杂度和空间复杂度,选择最合适的排序算法。

总的来说,内部排序是数据处理中不可或缺的一环。了解和掌握各种内部排序算法的特点和适用场景,对于提高数据处理效率、优化数据结构、以及实现高效算法都具有重要的意义。在未来的数据处理工作中,我们需要不断学习和研究新的排序算法和技术,以适应不断变化的数据处理需求。

外部排序

数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

外部排序,指的是当待排序的数据量过大,无法一次性装入内存时,需要使用外部存储设备如磁盘等进行排序的过程。这种排序方法通常涉及数据的分块、部分排序、归并等步骤,以适应大数据量的处理需求。

在现代数据处理的场景中,外部排序的应用非常广泛。例如,在处理海量日志文件、数据库查询结果、大数据分析等任务时,由于数据量庞大,无法一次性加载到内存中进行排序,因此需要使用外部排序算法。

外部排序的一个典型算法是k路归并排序。首先,将数据分割成若干个小块,每块的大小刚好能够装入内存。然后,使用内部排序算法(如快速排序、归并排序等)对每块数据进行排序,并将排序后的数据写回磁盘。接下来,使用多路归并算法将这些已排序的数据块合并成一个有序的大文件。在归并过程中,每次从各个数据块中读取一定数量的数据到内存中,进行比较和合并,然后将合并后的数据写回磁盘。这个过程不断重复,直到所有的数据块都被合并成一个有序的文件。

外部排序不仅需要考虑排序算法的效率,还需要考虑磁盘I/O操作、内存使用等因素。为了提高排序速度,可以采用一些优化策略,如增加归并路数、使用缓冲区来减少磁盘I/O次数、利用并行计算等。

此外,随着技术的发展,外部排序算法也在不断演进。例如,利用分布式存储和计算框架(如Hadoop、Spark等)进行外部排序,可以处理更大规模的数据集,并且提高排序的并行度和效率。

总的来说,外部排序是处理大数据量排序问题的重要手段。通过合理的算法设计和优化,可以在有限的内存和磁盘空间下,实现高效、稳定的数据排序。

二、排序运用

在这里插入图片描述

在这里插入图片描述

三、常见的排序算法

在这里插入图片描述
直接插入排序

希尔排序

选择排序

堆排序

冒泡排序

快速排序

归并排序

四、排序性能检测代码

排序性能检测代码是用于评估不同排序算法性能的代码。它通常包括生成随机数据集、实现多种排序算法、计时每种算法的执行时间,并比较它们的性能。这种代码可以帮助开发者选择最适合特定应用场景的排序算法。

总结:排序性能检测代码通过生成随机数据、实现多种排序算法并比较它们的执行时间,来评估不同排序算法的性能,帮助开发者选择最佳算法。

// 排序实现的接口
 
// 插入排序
	void InsertSort(int* a, int n);
 
// 希尔排序
	void ShellSort(int* a, int n);
 
// 选择排序
	void SelectSort(int* a, int n);
 
// 堆排序
	void AdjustDwon(int* a, int n, int root);
	void HeapSort(int* a, int n);
 
// 冒泡排序
	void BubbleSort(int* a, int n)
 
// 快速排序递归实现
// 快速排序hoare版本
	int PartSort1(int* a, int left, int right);
// 快速排序挖坑法
	int PartSort2(int* a, int left, int right);
// 快速排序前后指针法
	int PartSort3(int* a, int left, int right);
	void QuickSort(int* a, int left, int right);
 
// 快速排序 非递归实现
	void QuickSortNonR(int* a, int left, int right)
 
// 归并排序递归实现
	void MergeSort(int* a, int n)
// 归并排序非递归实现
	void MergeSortNonR(int* a, int n)
 
// 计数排序
	void CountSort(int* a, int n)
 
// 测试排序的性能对比
	void TestOP()
	{
	 srand(time(0));
	 const int N = 100000;
	 int* a1 = (int*)malloc(sizeof(int)*N);
	 int* a2 = (int*)malloc(sizeof(int)*N);
	 int* a3 = (int*)malloc(sizeof(int)*N);
	 int* a4 = (int*)malloc(sizeof(int)*N);
	 int* a5 = (int*)malloc(sizeof(int)*N);
	 int* a6 = (int*)malloc(sizeof(int)*N);
	 int* a7 = (int*)malloc(sizeof(int)*N);
 
	 for (int i = 0; i < N; ++i)
	 {
	 	a1[i] = rand();
	 	a2[i] = a1[i];
	 	a3[i] = a1[i];
	 	a4[i] = a1[i];
	 	a5[i] = a1[i];
	 	a6[i] = a1[i];
	 	a7[i] = a1[i];
 	} 
	int begin1 = clock();// 插入排序
	InsertSort(a1, N);
	int end1 = clock();

	int begin7 = clock();// 冒泡排序
	BubbleSort(a7, N);
	int end7 = clock();

	int begin2 = clock();// 希尔排序
	ShellSort(a2, N);
	int end2 = clock();

	int begin3 = clock();// 选择排序
	SelectSort(a3, N);
	int end3 = clock();

	int begin4 = clock();// 堆排序
	HeapSort(a4, N);
	int end4 = clock();

	int begin5 = clock();// 快速排序前后指针法
	QuickSort(a5, 0, N - 1);
	int end5 = clock();

	int begin6 = clock();// 归并排序递归实现
	MergeSort(a6, N);
	int end6 = clock();

	printf("InsertSort:%d\n", end1 - begin1);
	printf("BubbleSort:%d\n", end7 - begin7);

	printf("ShellSort:%d\n", end2 - begin2);
	printf("SelectSort:%d\n", end3 - begin3);
	printf("HeapSort:%d\n", end4 - begin4);
	printf("QuickSort:%d\n", end5 - begin5);
	printf("MergeSort:%d\n", end6 - begin6);

	free(a1);
	free(a2);
	free(a3);
	free(a4);
	free(a5);
	free(a6);
	free(a7);
	}

下面是对该代码的详细解释:

函数定义:void TestOP() 是一个函数,它没有返回值(void)并且不接受任何参数。

  1. 初始化随机数生成器:
    srand(time(0));:使用当前时间作为种子初始化随机数生成器。这样每次运行程序时,生成的随机数序列都会不同。

  2. 内存分配:
    代码为7个整数数组(a1 到 a7)分配了内存,每个数组都有 N(100,000)个整数。这些数组用于存储要排序的数据。

  3. 填充数组:
    在一个for循环中,所有数组(除了 a7)都被填充了随机数。a7 数组没有被正确初始化,这是一个错误。

  4. 排序和计时:
    代码使用 clock() 函数来测量每种排序算法的执行时间。clock() 函数返回程序执行的时钟周期数。

每种排序算法(插入排序、冒泡排序、希尔排序、选择排序、堆排序、快速排序和归并排序)都被调用一次,并计算其执行时间。

  1. 输出结果:
    使用 printf 函数输出每种排序算法的执行时间。

  2. 释放内存:
    使用 free() 函数释放之前为数组分配的内存。

注意
由于所有数组(除了 a7)都使用了相同的随机数序列进行初始化,因此这些排序算法的比较是公平的。

clock() 函数的结果可能受到多种因素的影响,包括CPU速度、负载和其他正在运行的程序。因此,这些结果只能作为大致的性能比较,而不是精确的性能指标。

srand()

srand()是C语言中的一个函数,用于设置随机数生成器的种子。它的原型是:

void srand(unsigned int seed);

其中,seed是一个整数作为种子。通过设置种子,srand()函数可以改变随机数序列的起点。每次调用srand()函数,生成的随机数序列将会根据种子重新开始。

一般情况下,我们可以使用系统时间作为种子,以使生成的随机数序列每次都不一样,例如:

srand(time(NULL));

在调用srand()函数之后,我们可以使用rand()函数来生成随机数。每次调用rand()函数,都会返回一个伪随机数,这个数的取值范围通常是0RAND_MAX。需要注意的是,生成的随机数是伪随机数,其实质是通过算法计算得到的,并非真正意义上的随机数。

总结来说,srand()函数用于设置随机数生成器的种子,以改变随机数序列的起点;而rand()函数用于生成伪随机数序列。

clock()

clock() 函数是C和C++中的一个标准库函数,用于返回程序运行的CPU时间。它的原型如下所示:

#include <time.h>

clock_t clock(void);

clock() 函数返回一个 clock_t 类型的值,表示自程序开始执行以来所经过的时钟周期数。时钟周期的长度取决于系统和编译器的实现。

需要注意的是,clock() 函数返回的是CPU时间,而不是实际的墙钟时间(即现实世界中的时间)。CPU时间是指程序运行所消耗的CPU时间,包括程序执行和系统调用等。因此,如果程序在多个CPU核心上运行,clock() 函数返回的值可能会大于墙钟时间。

使用 clock() 函数可以用来测量程序的执行时间,例如用于性能分析和优化。可以通过在程序的开始和结束处调用 clock() 函数并计算差值来获得程序的CPU时间消耗。

需要注意的是,clock() 函数返回的值是一个CPU时间计数器的累积值,因此不能直接用于表示程序执行的实际时间。如果需要测量实际时间,可以使用其他函数和方法,如 time() 函数和 chrono 库中的类。

五、oj排序测试代码

排序OJ(可使用各种排序跑这个OJ)


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

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

相关文章

基于php健身房管理系统flask-django-python

根据现实需要&#xff0c;此系统我们设计出一下功能&#xff0c;主要有以下功能模板。 &#xff08;1&#xff09;前台功能&#xff1a;首页、运动器材、教练信息、营业信息、公告栏、在线留言、后台管理、个人中心。 &#xff08;2&#xff09;会员功能&#xff1a;首页、个人…

力扣700 二叉搜索树中的搜索 Java版本

文章目录 题目描述代码 题目描述 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 null 。 示例 1: 输入&#xff1a;root [4,2,7,…

C++_day6:2024/3/18

作业1&#xff1a;编程题&#xff1a; 以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴子等。现在…

一文读懂Partisia区块链的MOCCA 方案:让资产管理可信且可编程

在今年 1 月&#xff0c;Partisia Blockchain 在参加了达沃斯世界经济论坛时&#xff0c;宣布推出一种全新的链上资产管理方案 MOCCA &#xff08;MPC On-Chain Custody Advanced&#xff09;&#xff0c;即多方计算链上托管高级解决方案。据悉该方案建立在 Partisia Blockchai…

腾讯云服务器多少钱一年?2024报价曝光,请查收

腾讯云服务器多少钱一年&#xff1f;61元一年起。2024年最新腾讯云服务器优惠价格表&#xff0c;腾讯云轻量2核2G3M服务器61元一年、2核2G4M服务器99元一年可买三年、2核4G5M服务器165元一年、3年756元、轻量4核8M12M服务器646元15个月、4核16G10M配置32元1个月、312元一年、8核…

海外代理IP在跨境电商中的五大应用场景

在我国跨境电商的发展中&#xff0c;海外代理IP的应用日益广泛&#xff0c;它不仅帮助商家成功打入国际市场&#xff0c;还为他们在多变的全球电商竞争中保持优势。下面是海外代理IP在跨境电商中五个关键的应用场景。 1、精准的市场分析 了解目标市场的消费者行为、产品趋势以…

【必撸】:白嫖Okapi x B²测试网声誉NFT,一鱼双吃保姆级教程

这期教程写起来是真的麻烦&#xff0c;如果有帮助还请用发财的手点个赞&#xff0c;谢谢 简介&#xff1a;BTC L2头号种子选手B Network热度很高就不过多介绍了&#xff0c;这里主要说一下Okapi。Okapi 是Web3链上验证的内容、声誉认证平台&#xff0c;它提供一个值得信赖的平…

Mysql数据库概念与安装

目录 一、数据库概述 1、数据库的基本概念 2、数据库管理系统&#xff08;DBMS&#xff09; 2.1 数据库管理系统概念 2.2 数据库管理系统工作模式 3、数据库系统&#xff08;DBS&#xff09; 3.1 数据库系统概念 3.2 数据库系统发展史 4、关系型数据库与非关系型数据库…

鸿蒙Harmony应用开发—ArkTS声明式开发(绘制组件:Ellipse)

椭圆绘制组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Ellipse(options?: {width?: string | number, height?: string | number}) 从API version 9开始&#xff0…

ReoGrid电子表格组件

ReoGrid电子表格组件 ReoGrid 是一个基于 .NET 的电子表格组件&#xff0c;供开发人员使用。它允许用户将电子表格功能嵌入到其 .NET 应用程序中。ReoGrid 提供类似于流行的电子表格软件&#xff08;如 Microsoft Excel&#xff09;的功能&#xff0c;包括以编程方式创建、编辑…

Linux字符设备与I2C驱动结合使用

引言 在Linux操作系统中&#xff0c;设备驱动程序充当硬件和软件之间的桥梁。字符设备驱动是一种特殊类型的驱动&#xff0c;它允许用户以字节流的形式访问硬件设备。这些设备包括键盘、鼠标、串口等。在本博客中&#xff0c;我们将探讨Linux字符设备驱动的基础知识&#xff0…

u-boot-2017.09 make配置过程分析

概述 本文基于firefly RK3588Q SDK uboot配置过程进行分析&#xff0c;环境如下&#xff1a; 编译环境&#xff1a;Ubuntu 20.04 LTS 编译工具&#xff1a;aarch64-linux-gnu- 代码版本&#xff1a;u-boot v2017.09 配置文件&#xff1a;rk3588_defconfig Uboot配置单板 …

【数组、字符串】算法例题

每个题的【方法1】是自己的思路&#xff0c;【其他方法】是力扣上更优的解题思路 目录 一、数组、字符串 1. 合并两个有序数组 ① 2. 移除元素 ① 3. 删除有序数组中的重复项 ① 4. 删除有序数组中的重复项 II ② 5. 多数元素 ① 6. 轮转数组 ② 7. 买卖股票的最佳时机…

瑞_Redis_短信登录

文章目录 项目介绍1 短信登录1.1 项目准备1.1.1 导入SQL1.1.2 导入后端项目1.1.3 导入前端项目 1.2 基于Session实现登录流程1.2.1 功能流程介绍1.2.1.1 发送短信验证码1.2.1.2 短信验证码登录、注册1.2.1.3 校验登录状态 1.2.2 实现发送短信验证码功能1.2.2.1 页面流程1.2.2.2…

2024单商户微信小程序商城源码

2024单商户微信小程序商城源码 1.框架采用全新thinkphp6事件开发设计layuiuniapp进行设计&#xff0c;代码完全重构&#xff0c;支持百万级! 2.前端以layui uniapp模块化开发; 3.数据导出采用phpExce1,使数据更加直观&#xff0c;更方便于管理统计; 4.插件钩子机制&#xff0…

突发!半导体巨头关闭上海公司,重组中国区业务!

据韩媒消息&#xff0c;韩国最大的半导体巨头之一 SK 海力士正在重组中国区业务&#xff0c;计划关闭其在上海的子公司&#xff0c;该子公司成立于 2006 年。 根据发布的 2023 年审计报告&#xff0c;去年四季度以来该公司一直在清算其上海子公司&#xff0c;并计划将业务重心…

基于java的宠物信息交流平台设计(含源文件)

随着世界经济信息化、全球化的到来和互联网的飞速发展&#xff0c;推动了各行业的改革。若想达到安全&#xff0c;快捷的目的&#xff0c;就需要拥有信息化的组织和管理模式&#xff0c;建立一套合理、动态的、交互友好的、高效的“多鱼”旧物交易平台。当前的信息管理存在工作…

【第十二章】改进神经网络学习方式-过拟合与正则化

前言 诺贝尔奖获得者、物理学家恩里科费米曾被问及对一位同事提出的数学模型作为重要未解物理问题的解决方案的看法。该模型与实验结果非常吻合&#xff0c;但费米持怀疑态度。他询问该模型中有多少自由参数可供设置。答案是“四个”。费米回答道:“我记得我的朋友约翰尼冯诺伊…

基于Spring Boot+Vue的智慧图书管理系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 一、项目简介 如今社会上各行各业&…

力扣---验证二叉搜索树---前根/中根/后根遍历

题目解析参考&#xff1a;验证二叉搜索树_哔哩哔哩_bilibili 一开始做呢&#xff0c;就跟这位老兄一样&#xff1a; 因为没有考虑到5和3的比较 接下来走入整体&#xff1a; 先根遍历解法&#xff1a; 首先 每个点其实都有范围&#xff0c;比如根节点的范围在(-INF,INF)&…