数据结构--》掌握数据结构中的排序算法

        当我们面对海量数据时,如何高效地将其排序是数据结构领域中一个重要的问题。排序算法作为其中的关键部分,扮演着至关重要的角色。

        无论你是初学者还是进阶者,本文将为你提供简单易懂、实用可行的知识点,帮助你更好地掌握排序算法在数据结构和算法中的重要性,进而提升算法解题的能力。接下来让我们开启数据结构与算法的奇妙之旅吧。

        当我们需要对一组数据进行排序时,就需要使用排序算法。通常情况下,我们会将一组数据按照一定的规则进行排列,从而使其更易于查找和处理。

        常见的排序算法包括冒泡排序插入排序选择排序希尔排序归并排序快速排序等等。这些算法都有各自的优缺点,不同的应用场景适用不同的算法。因此,在实际开发中需要根据具体情况进行选择。接下来根据考研的大纲要求,着重对相关排序算法进行相应的讲解:

目录

插入排序

交换排序

选择排序

归并排序

基数排序


插入排序

算法思想:每次将一个待排序的记录按其关键字大小插入到前面已排好序的子序列中,直到全部记录插入完成。其实现的过程大致如下:

1)从第一个元素开始,认为它是已排序的区间。

2)取出下一个元素,在已经排好序的元素序列中从后向前扫描。

3)如果该元素(已排序)大于新元素,将该元素移到下一个位置。

4)重复步骤 3 直到找到已经排序的元素小于或者等于新元素的位置。

5)将新元素插入到该位置中。

用c语言实现插入排序算法:

void insertionSort(int arr[], int n) {int i, key, j;for (i = 1; i < n; i++) {key = arr[i];j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}
}

回顾重点,其主要内容整理成如下内容:

希尔排序:是一种基于插入排序的排序算法,也被称为缩小增量排序。它通过将待排序的元素分组,然后依次对每组的元素进行插入排序,最后再对整个序列进行一次插入排序。如下:

对生成的子表进行直接插入排序得到的结果如下:

直到d等于1的时候,得到的排序结果基本有序,然后进行直接插入排序得到最后的结果。

最终呈现的过程结果如下:

用c语言实现希尔排序算法: 

#include <stdio.h>void shellSort(int arr[], int n) {// 定义增量序列int gap, i, j, temp;for (gap = n / 2; gap > 0; gap /= 2) {// 内部使用插入排序对每个子序列进行排序for (i = gap; i < n; i++) {temp = arr[i];j = i;while (j >= gap && arr[j - gap] > temp) {arr[j] = arr[j - gap];j -= gap;}arr[j] = temp;}}
}int main() {int arr[] = {9, 5, 2, 7, 1, 8};int n = sizeof(arr) / sizeof(arr[0]);printf("原始数组:");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}shellSort(arr, n);printf("\n排序后数组:");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}return 0;
}

回顾重点,其主要内容整理成如下内容:

交换排序

交换排序是一种比较简单直观的排序算法,其主要思想是通过交换数组中相邻且不符合顺序要求的元素,将最大或最小的元素逐步“冒泡”到正确的位置。常用的交换排序算法有冒泡排序快速排序,下面将着重讲解一下这两种排序的相关实现:

冒泡排序:最基础的交换排序算法,其核心思想是从左到右,依次比较相邻的元素,将较大的元素交换到后面。该算法重复多次,每次将一个未排序的元素放到正确的位置,直到整个数组有序。冒泡排序的时间复杂度为 O(n^2)。

前后数值进行对比,小的前大的后,然后重复多次,直到将顺序从小到大弄出来

用c语言实现冒泡排序算法:  

#include <stdio.h>void bubbleSort(int arr[], int n) {int i, j, temp;for (i = 0; i < n-1; i++) {for (j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {// 交换相邻元素temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}
}int main() {int arr[] = {9, 5, 2, 7, 1, 8};int n = sizeof(arr) / sizeof(arr[0]);printf("原始数组:");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}bubbleSort(arr, n);printf("\n排序后数组:");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}return 0;
}

回顾重点,其主要内容整理成如下内容:

快速排序:是一种分治思想的排序算法,它将问题分割成较小的子问题,然后递归地求解这些子问题。在快速排序中,通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后再按此方法对两部分记录进行排序,递归地进行下去,直到整个序列有序。快速排序的平均时间复杂度为 O(n log n),最坏情况下时间复杂度为 O(n^2)。

用c语言实现快速排序算法:   

#include <stdio.h>// 交换数组中两个元素的值
void swap(int* a, int* b) {int temp = *a;*a = *b;*b = temp;
}// 将基准元素放在正确的位置,并返回该位置的索引
int partition(int arr[], int low, int high) {int pivot = arr[high];  // 将最后一个元素设为基准元素int i = (low - 1);  // i 初始化为最低索引的前一个for (int j = low; j <= high - 1; j++) {if (arr[j] < pivot) {i++;  // 找到一个比基准元素小的元素,将 i 向后移动swap(&arr[i], &arr[j]);  // 交换 arr[i] 和 arr[j]}}swap(&arr[i + 1], &arr[high]);  // 将基准元素放置在正确的位置return (i + 1);
}// 快速排序函数
void quickSort(int arr[], int low, int high) {if (low < high) {// 将基准元素放置在正确的位置int pi = partition(arr, low, high);// 递归调用快速排序函数quickSort(arr, low, pi - 1);  // 对基准元素左侧的子数组进行排序quickSort(arr, pi + 1, high);  // 对基准元素右侧的子数组进行排序}
}// 打印数组元素
void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");
}int main() {int arr[] = {9, 5, 2, 7, 1, 8};int n = sizeof(arr) / sizeof(arr[0]);printf("原始数组:");printArray(arr, n);quickSort(arr, 0, n - 1);printf("排序后数组:");printArray(arr, n);return 0;
}

回顾重点,其主要内容整理成如下内容: 

选择排序

选择排序是一种简单直观的排序算法,它的基本思路是每次从未排序的部分中选择最小(或最大)的元素,然后将其放置在已排序部分的末尾。重复这个过程直到所有元素都排好序。常用的交换排序算法有简单选择排序堆排序,下面将着重讲解一下这两种排序的相关实现:

简单选择排序:基本思路是每次从未排序的部分中选择最小(或最大)的元素,然后将其与未排序部分的第一个元素交换位置,即将最小元素放置在已排序部分的末尾。重复这个过程直到所有元素都排好序。

该算法的性能分析如下:

回顾重点,其主要内容整理成如下内容:

堆排序

堆排序是一种基于堆数据结构的排序算法,它利用了堆的特性来进行排序。堆是一种完全二叉树,分为最大堆和最小堆两种类型。

关于堆排序的讲解可以参考我之前的文章:解锁数据结构中树与二叉树的奥秘(二) 中的堆排序讲解,总结知识如下:

归并排序

归并排序是一种常用的排序算法,它基于分治的思想。归并排序将待排序的数组不断分割为较小的子数组,然后逐步将这些子数组合并成为有序的大数组,最终得到完全有序的数组。如下:

手算模拟归并排序的过程如下:

回顾重点,其主要内容整理成如下内容: 

基数排序

基数排序是一种非比较型整数排序算法,它是通过将待排序的整数按照位数划分成不同的数字组,然后对每个数字组进行排序,最终得到有序的整数数组。

得到的结果再以十位进行分配:

最终呈现的结果如下:

回顾重点,其主要内容整理成如下内容: 

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

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

相关文章

pdf怎么压缩?pdf文件缩小的方法在这里

PDF文件由于其跨平台、可打印性强等特点&#xff0c;成为了我们日常工作中经常使用的一种文件格式。然而&#xff0c;这种格式的文件有时候会因为过于庞大而给我们的存储和传输带来困扰&#xff0c;其实&#xff0c;这种情况只需要通过一些工具对PDF文件进行压缩&#xff0c;即…

【RocketMQ系列二】通过docker部署单机RocketMQ

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

小程序uView2.X框架upload组件上传方法总结+避坑

呈现效果: 1.1单图片上传 1.2多图片上传 前言:相信很多人写小程序会用到uView框架,总体感觉还算OK吧,只能这么说,肯定也会遇到图片视频上传,如果用到这个upload组件相信你,肯定遇到各种各样的问题,这是我个人总结的单图片和多图片上传方法. uView2.X框架:uView 2.0 - 全面兼容…

4.Python-用Python,Ajax实现MySQL数据库的新增数据

题记 用python&#xff0c;ajax实现mysql数据库的新增数据。以下是一个简单的实例和操作过程。 安装flask模块 pip install flask 安装mysql.connector模块 pip install mysql-connector-python 编写app.py文件 app.py文件如下&#xff1a; 块引用可能显示不完整&#x…

一键切换IP地址:电脑IP更改的简便方法

今天我要和大家分享一个电脑IP更改的简便方法——一键切换IP地址。如果您想要更改电脑的IP地址&#xff0c;无需繁琐的设置和复杂的步骤&#xff0c;只需使用以下简单的方法&#xff0c;即可轻松实现IP地址的切换。让我们开始吧&#xff01; 1、使用批处理脚本 批处理脚本是一…

java项目之学生综合考评管理系统()

项目简介 学生综合考评管理系统实现了以下功能&#xff1a; 管理员&#xff1a;个人中心、通知公告管理、班级管理、学生管理、教师管理&#xff0c;课程信息管理、作业布置管理、作业提交管理、留言信息管理、课程成绩管理。学生&#xff1a;个人中心、通知公告管理、教师管…

OpenCV学习笔记-环境搭建

文章目录 概述下载安装Visual Studio 2022下载安装OpenCVVisual Studio 配置配置包含路径配置库路径配置链接器配置环境变量Path路径 测试C测试Python 测试 概述 OpenCV&#xff08;Open source computer vision&#xff09;是一个跨平台的计算机视觉和机器学习开源库&#xf…

详解RocketMQ消息存储原理

本文基于RocketMQ 4.6.0进行源码分析 一. 存储概要设计 RocketMQ存储的文件主要包括CommitLog文件、ConsumeQueue文件、Index文件。RocketMQ将所有topic的消息存储在同一个文件中&#xff0c;确保消息发送时按顺序写文件&#xff0c;尽最大的能力确保消息发送的高性能与高吞吐…

旅游票务商城小程序的作用是什么

随着环境放开&#xff0c;旅游行业恢复了以往的规模&#xff0c;本地游、外地游成为众多用户选择&#xff0c;而在旅游时&#xff0c;不少人会报名旅行团前往各风景热点游玩&#xff0c;对旅游票务经营者而言&#xff0c;市场高需求的同时也面临一些难题。 对旅游票务经营商家…

四、RIP动态路由实验

拓扑图&#xff1a; 基本ip的配置已经配置好了&#xff0c;接下来对两台路由器配置rip协议&#xff0c;两台PC进行跨网段通讯 RIPv1版本只能识别ABC的大类网段&#xff0c;不能区分子网掩码&#xff0c;v2版本可以识别子网掩码 首先进入R1&#xff0c;进入rip&#xff0c;宣告…

springboot 使用RocketMQ客户端生产消费消息DEMO

创建springboot项目省略 项目依赖 注意&#xff1a;当前客户端版本是 5.1.3 &#xff0c;安装的rocketmq服务的版本要与其对应 <properties><java.version>11</java.version><rocketmq-client-java-version>5.1.3</rocketmq-client-java-version&…

Annoy vs Milvus:哪个向量数据库更适合您的AI应用?知其然知其所以然

1. Annoy vs Milvus简介 Annoy 和 Milvus 都是用于向量索引和相似度搜索的开源库&#xff0c;它们可以高效地处理大规模的向量数据。 Annoy&#xff08;Approximate Nearest Neighbors Oh Yeah&#xff09;&#xff1a; Annoy 是一种近似最近邻搜索算法&#xff0c;它通过构…

Flink中KeyBy、分区、分组的正确理解

1.Flink中的KeyBy 在Flink中&#xff0c;KeyBy作为我们常用的一个聚合类型算子&#xff0c;它可以按照相同的Key对数据进行重新分区&#xff0c;分区之后分配到对应的子任务当中去。 源码解析 keyBy 得到的结果将不再是 DataStream&#xff0c;而是会将 DataStream 转换为 Key…

同源策略和跨域问题

1.跨域问题产生的原因 浏览器的同源策略影响&#xff0c;同源策略是一种安全机制&#xff0c;它限制了一个网页中的脚本只能访问同源的资源。 跨源网络访问的三种方式&#xff1a;跨域写操作&#xff0c;跨域资源嵌入&#xff0c;跨域读操作 2.跨域问题案例 ip和域名不一致…

微信小程序底部tabBar不显示图标

现场还原 在设置微信小程序底部tabBar导航图标时&#xff0c;无论如何操作均无法显示在界面上 解决思路 问题1 图标类型 一开始以为不支持png类型&#xff0c;但查看官方API仅提示ICON尺寸大小 打开其他项目可以正常展示&#xff0c;排除图标类型问题 iconPath string 否 …

UE4和C++ 开发-常用的宏(二)UPROPERTY(类似于Unity中C#的特性[SerializeField])

UPROPERTY的作用类似于Unity中C#的特性[SerializeField]或者Godot中的export。目的就是通过反射把属性暴露在蓝图或实例的细节面板。 属性说明符&#xff08;Property Specifiers&#xff09;

unity2022版本 实现手机虚拟操作杆

简介 在许多移动游戏中&#xff0c;虚拟操纵杆是一个重要的用户界面元素&#xff0c;用于控制角色或物体的移动。本文将介绍如何在Unity中实现虚拟操纵杆&#xff0c;提供了一段用于移动控制的代码。我们将讨论不同类型的虚拟操纵杆&#xff0c;如固定和跟随&#xff0c;以及如…

进阶JAVA篇- DateTimeFormatter 类与 Period 类、Duration类的常用API(八)

目录 1.0 DateTimeFormatter 类的说明 1.1 如何创建格式化器的对象呢&#xff1f; 1.2 DateTimeFormatter 类中的 format&#xff08;LocalDateTime ldt&#xff09; 实例方法 2.0 Period 类的说明 2.1 Period 类中的 between(localDate1,localDate2) 静态方法来创建对象。 3.…

京东优惠券怎么找?

京东优惠券怎么找&#xff1f; 1、手机安装「草柴」后&#xff0c;打开京东挑选要购买的商品&#xff1b; 2、挑选好京东商品后&#xff0c;点击右上角的「分享」&#xff0c;并点击「复制链接」&#xff1b; 3、将复制的京东商品链接&#xff0c;粘贴到草柴输入框&#xff0c…

antd pro form 数组套数组 form数组动态赋值 shouldUpdate 使用

antd form中数组套数组 form数组动态变化 动态赋值 需求如上&#xff0c;同时添加多个产品&#xff0c;同时每个产品可以增加多台设备&#xff0c;根据设备增加相应编号&#xff0c;所以存在数组套数组&#xff0c;根据数组值动态变化 使用的知识点 form.list form中的数组…