嵌入式中十大经典排序算法(代码实现),建议收藏

前言

兜兜转转,时间如白驹过隙。时间证明了一个道理,学啥忘啥,学的越快忘得越快,还不如踏踏实实写点笔记心得来的实在。

编程初学期间,排序算法是让人抓头最多的一块。为什么我连最简单的冒泡排序都理解不了,我是不是不选错专业了,很多人会有这样的疑问,然后就有人做gif冒泡懵逼排序,别说,还挺形象的。

其实排序算法这块,着急不得,这个排序算法不会就换一个排序算法来学,总有一种排序算法你能够理解的,等需要用到排序的时候,你只要会一种就可以了。

在这里我列举了7中常见的排序算法并用C语言实现,你们可能就要问了,不是十种吗?怎么还能缺斤短两,不是我不会写啊,是写起来麻烦,你们也用不到后面那几种,跟别说去研究了,能看懂常见的七种排序算法你就能在学校里横着走了。

目录

一、冒泡排序

二、选择排序

三、插入排序

四、快速排序

五、希尔排序

六、归并排序

七、桶(基数)排序

01 冒泡排序

相信大家最熟悉的就是冒泡排序了,这个我就不多说

直接上动图演示原理,外加代码实现冒泡排序:

图片

C语言代码实现:

void BubbleSort(int arr[], int n){  //从小到大排序 相邻来两个数比较,将大的数字往后放  for (int i = 0; i < n - 1; i++)      //n-1是因为数组下标最大为n-1 要进行10轮比较  {    //n-1是因为数组下标最大为n-1 要进行10次比较,再减i是因为每最后的i个元素已经有序不需要继续排序    for (int j = 0; j < n - 1 - i; j++)    {      if (arr[j] > arr[j + 1])      //两两比较,将小的数据放前面      {        swap(arr, j + 1, j);        //交换arr数组arr[j+1]和arr[j]的值      }    }  }}//交换函数后面就不列举了,凡是swap都是下面代码实现的void swap(int arr[], int x, int y){  int temp = arr[x];  arr[x] = arr[y];  arr[y] = temp;}

02选择排序

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾,重复操作。

动图演示原理,外加代码实现选择排序:

图片

C语言代码实现:​​​​​​​

void SelectSort(int arr[], int n){  for (int i = 0; i < n - 1; i++)  {    for (int j = i + 1; j < n; j++)    {      if (arr[i] > arr[j])      {        swap(arr, i, j);  //交换arr数组arr[i]和arr[j]的值      }    }  }}

03插入排序

插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的,就是将未排序的数字插入到已排序的数列中

动图演示原理,外加代码实现插入排序:

图片

C语言代码实现:​​​​​​​

void InsertSort(int arr[], int n){  int tempVal;  for (int i = 1, j; i < n; i++)  {    tempVal = arr[i];  //保存要插入的值    for (j = i - 1; tempVal < arr[j] && j >= 0; --j)  //数据往后移动,给要插入的值腾位    {      arr[j + 1] = arr[j];    }    arr[j + 1] = tempVal;  //插入数据  }}

04快速排序

快速排序由于涉及到递归,理解起来难度是最大的,但是如果你静下心来独自对一组数组用快速排序的原理进行排序就能够很快的理解它,也能够理解递归的原理。

动图演示原理,外加代码实现选择排序:

图片

C语言代码实现:​​​​​​​

void QuickSort(int arr[], int left, int right){  if (left >= right) return;  //只有一个元素不排  int i = left, j = right;  while (i < j)  {    while (i < j&&arr[j] >= arr[left])  //从右向左找第一个小于arr[left]的数      --j;    while (i < j&&arr[i] < arr[left])  //从左向右找第一个大于等于arr[left]的数      ++i;    if (i < j)      swap(arr, i, j);  }  QuickSort(arr, left, i - 1);//排左边  QuickSort(arr, i + 1, right);//排右边}

05希尔排序

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。插入排序是将未排序的数字插入到已排序数列中,而希尔排序是将一个已排序的数列插入到另一个已排序的数列中。

示意图演示原理,外加代码实现希尔排序:

图片

C语言代码实现:

void ShellSort(int arr[], int n){  int tempVal, j;  int jump = n >> 2;      //步长值  while (jump != 0)  {    for (int i = jump; i < n; i++)    {      tempVal = arr[i];  //保存待排序的第一个数,也就是待插入的数      for (j = i - jump; j >= 0 && tempVal < arr[j]; j -= jump)      {        arr[j + jump] = arr[j];      }      arr[j + jump] = tempVal;    }    jump = jump >> 1;    //步长值减半  }}

06归并排序

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。

示意图演示原理,外加代码实现归并排序:

图片

C语言代码实现:

void MergeSort(int arr[], int left, int right){  if (left >= right)//递归的终止条件,left == right证明这个区间只有一个元素,不需要再拆了    return;  int mid = ((right - left) >> 1) + left;//求中点  MergeSort(arr, left, mid);    //拆分左  MergeSort(arr, mid + 1, right);  //拆分右  //并操作  _merge_in_arr(arr, left, mid, right);}
void _merge_in_arr(int arr[], int left, int mid, int right){  int length = right - left + 1;          //定义一个辅助的空间的长度  int *pData = (int*)malloc(sizeof(int)*length);//分配一个动态内存来调整元素的位置  memset(pData, 0, sizeof(int)* length);
  //合并  int low = left;    //左边区间的起始下标  int hig = mid + 1;  //右边区间的起始下标  int index = 0;    //辅助数组的下标
  while (hig <= right)//右区间没有合并完  {    while (low <= mid && arr[low] <= arr[hig])//证明左区间没有合并完,且左区间的值小于右区间的值    {      pData[index] = arr[low];      //把左边的值放进辅助数组      low++;                //左边往高位移,下一次需要判断左边的新下标      index++;              //下一次放进辅助数组的新下标    }    if (low > mid)  //证明左区间已经放完      break;
    while (hig <= right && arr[low] > arr[hig])//证明右区间没有合并完,且左区间的值大于右区间的值    {      pData[index] = arr[hig];      //把右边的值放进辅助数组      hig++;                //右边往高位移,下一次需要判断右边的新下标      index++;              //下一次放进辅助数组的新下标    }  }
  //到这一步,证明起码有一个区间已经合并完成  if (hig <= right)  //证明右边没有完成    memmove(&pData[index], &arr[hig], sizeof(int)* (right - hig + 1));  if (low <= mid)    //证明左边没有完成    memmove(&pData[index], &arr[low], sizeof(int)* (mid - low + 1));
  //把所有区间都合并到了辅助区间  memmove(&arr[left], pData, sizeof(int)* length);  free(pData);  //释放空间}

07桶排序

桶排序是典型的空间换时间,在对整数排序中,没有什么算法能比它还快,但是在空间浪费上,它是祖宗。

示意图演示原理,外加代码实现桶排序:

图片

C语言代码实现:

void radix_sort(int arr[], size_t len){  int**temp = (int **)malloc(sizeof(int) * 10);  //10行  //申请动态内存   辅助数组temp[10][];  for (int i = 0; i < 10; i++)  {    temp[i] = (int *)malloc(sizeof(int)*len);  }
  for (int i = 1; i <= 100; i *= 10)//循环数值可能有的位数  {    for (int x = 0; x < 10; ++x)//辅助数组行循环    {      for (int y = 0; y < len; ++y)//辅助数组列循环      {        temp[x][y] = -1;//辅助数组的初始化赋值,-1表示在arr里面不可能出现的数值       }    }    //arr数组中的元素放入辅助数组    for (int m = 0; m < len; ++m)    {      int index = (arr[m] / i) % 10;      temp[index][m] = arr[m];    }    //把辅助数组的内容放回待排序数组    int k = 0;//待排序的下标    for (int x = 0; x < 10; x++)    {      for (int y = 0; y < len; ++y)      {        if (temp[x][y] != -1)          arr[k++] = temp[x][y];      }    }  }  //释放内存  for (int i = 0; i < 10; i++)  {    free(temp[i]);  }  free(temp);}

算法复杂度

这个算法的复杂度纯理论,我就放到最后来讲

一个时间复杂度,一个空间复杂度

一个稳定,一个不稳定

稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面

不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面

时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律

空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

附录:

图片

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【动态规划】【状态压缩】LCP04 覆盖

作者推荐 【广度优先搜索】【网格】【割点】【 推荐】1263. 推箱子 本文涉及知识点 动态规划汇总 LCP04 覆盖 你有一块棋盘&#xff0c;棋盘上有一些格子已经坏掉了。你还有无穷块大小为1 * 2的多米诺骨牌&#xff0c;你想把这些骨牌不重叠地覆盖在完好的格子上&#xff0…

C#学习总结

1、访问权限 方法默认访问修饰符&#xff1a;private 类默认访问修饰符&#xff1a;internal 类的成员默认访问修饰符&#xff1a;private 2、UserControl的使用 首先添加用户控件 使用时一种是通过代码添加&#xff0c;一种是通过拖动组件到xaml中

音频的“隐形保镖”——音频数字水印

在互联网时代&#xff0c;多媒体数字资源可以快捷地传播和获取&#xff0c;但同时也导致了数字音频产品的非法扩散、非法拷贝和非法篡改猖獗&#xff0c;数字音频产品的完整性和版权保护问题越来越凸显。文档和图像可以添加水印&#xff0c;音频同样可以添加水印&#xff0c;让…

【递归版】归并排序算法(1)

目录 MergeSort归并排序 整体思想 图解分析 代码实现 时间复杂度 递归&归并排序VS快速排序 MergeSort归并排序 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法&#xff0c;该算法是采用分治法&#xff08;Divide and Conquer&a…

堆排序法的名字由来,排序步骤是什么,最坏情况下的排序次数如何计算得来的呢?

问题描述&#xff1a;堆排序法的名字由来&#xff0c;排序步骤是什么&#xff0c;最坏情况下的排序次数如何计算得来的呢&#xff1f; 问题解答&#xff1a; 堆排序法的名字来源于它使用了堆这种数据结构。堆是一种特殊的树形数据结构&#xff0c;具有以下特点&#xff1a;在…

基于RK3399 Android11适配OV13850 MIPI摄像头

目录 1、原理图分析2、编写和配置设备树3、调试方法4、遇到的问题与解决5、补丁 1、原理图分析 从上图可看出&#xff0c;我们需要关心的&#xff0c;①MIPI数据和时钟接口使用的是MIPI_TX1/RX1 ②I2C使用的是I2C4总线 ③RST复位引脚使用的是GPIO2_D2 ④PWDN使用的是GPIO1_C7 ⑤…

A星寻路算法详解

A星寻路算法 前言 A星寻路算法是静态路网中求解最短路径最有效的直接搜索方法&#xff0c;也是解决许多搜索问题的有效算法&#xff0c;它可以应对包括复杂地形&#xff0c;各种尺度的障碍物以及不同地形的路径规划问题。掌握A星寻路算法能够提高路径规划效率&#xff0c;应对…

大模型参数高效微调

参数高效微调目的 PEFT技术旨在通过最小化微调参数的数量和计算复杂度&#xff0c;来提高预训练模型在新任务上的性能&#xff0c;从而缓解大型预训练模型的训练成本。这样一来&#xff0c;即使计算资源受限&#xff0c;也可以利用预训练模型的知识来迅速适应新任务&#xff0…

域名 SSL 证书信息解析 API 数据接口

域名 SSL 证书信息解析 API 数据接口 网络工具&#xff0c;提供域名 SSL 证书信息解析&#xff0c;多信息查询&#xff0c;毫秒级响应。 1. 产品功能 提供域名 SSL 证书信息解析&#xff1b;最完整 SSL 属性信息解析&#xff1b;支持多种元素信息抽取&#xff0c;包括主题的可…

【Java程序设计】【C00278】基于Springboot的数码论坛管理系统(有论文)

基于Springboot的数码论坛管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的数码论坛系统 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页、…

Linux:Jenkins:GitLab+Maven+Jenkins的部署

1.环境 我这里准备了三台centos7 1.用于部署gitlab 运行内存&#xff1a;6G 名字&#xff1a;Jenkins-GitLab 192.168.6.1 2.用于部署jenkins 运行内存&#xff1a;2G 名字&#xff1a;Jenkins-server 192.168.6.2 3.用于打包测试…

全面解析企业财务报表系列之五:阅读财报结构、顺序、模块与不同侧重

全面解析企业财务报表系列之五&#xff1a;阅读财报结构、顺序、模块与不同侧重 一、明确本次报表分析的目的二、确定报表分析的重点项目三、重点分析项目之间的联系四、资产负债表的阅读五、利润表的阅读六、现金流量表的阅读七、综合分析 一、明确本次报表分析的目的 报表的…

VBA即用型代码手册:立即保护所有工作表Code及插入多工作表Code

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…

【C语言】指针变量未初始化

我们知道&#xff1a;全局变量未赋初值&#xff0c;编译器会直接赋值为0&#xff1b;局部变量如果未赋初值&#xff0c;则会维持上一状态保存在该地址上的值&#xff0c;这个值是随机的。把这个值赋值给局部变量是没有意义的。 但是指针变量是如何解决不赋初值&#xff1f; 指…

探索设计模式的魅力:状态模式揭秘-如何优雅地处理复杂状态转换

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;并且坚持默默的做事。 探索设计模式的魅力&#xff1a;状态模式揭秘-如何优雅地处理复杂状态转换 文章目录 一、案例…

力扣 187. 重复的DNA序列

1.题目 DNA序列 由一系列核苷酸组成&#xff0c;缩写为 A, C, G 和 T.。 例如&#xff0c;"ACGAATTCCG" 是一个 DNA序列 。 在研究 DNA 时&#xff0c;识别 DNA 中的重复序列非常有用。 给定一个表示 DNA序列 的字符串 s &#xff0c;返回所有在 DNA 分子中出现不止一…

如何连接ACL认证的Redis

点击上方蓝字关注我 应用程序连接开启了ACL认证的Redis时与原先的方式有差别&#xff0c;本文介绍几种连接开启ACL认证的Redis的Redis的方法。 对于RedisACL认证相关内容&#xff0c;可以参考历史文章&#xff1a; Redis权限管理体系(一&#xff09;&#xff1a;客户端名及用户…

Python之numpy

目录 安装 ndarray 说明文档 NumPy(Numerical Python) 是 Python 语言的一个扩展程序库&#xff0c;支持大量的维度数组与矩阵运算&#xff0c;此外也针对数组运算提供大量的数学函数库。 安装 pip3 install --user numpy scipy matplotlib ndarray NumP提供了 N 维数组…

国家之间的竞争绝不仅仅是几个AI软件的竞争

国家之间的竞争应该不仅仅是几个AI软件的竞争&#xff0c;而更多地是人机环境系统生态的竞争。在这种观点下&#xff0c;国家之间的竞争被视为一个更为复杂和综合的竞争过程&#xff0c;涉及到人类、技术系统以及周围环境的综合作用。 在人机环境系统生态的竞争中&#xff0c;人…

Stable Diffusion 3正式发布,旨在巩固其在AI图像领域相对于Sora和Gemini的领先地位

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…