【转载】[经验] 嵌入式stm32实用的排序算法 - 交换排序
| Ⅰ、写在前面
前面写了关于ADC采集电压的文章,大家除了求平均的方式来处理采样值,还有没有使用到其他的方式来处理采集值呢? 在某些情况下就需要对一组数据进行排序,并提取头特定的数据出来使用。 排序的应用场合很多,我这里就不再一一举例说明,掌握排序的基本算法,到时候遇到就有用武之地。 Ⅱ、排序算法分类 1.按存储分类:内部排序和外部排序 内部排序:是数据记录在内存中进行排序; 外部排序:是因排序的数据很大,一般一次不能容纳全部的排序记录,在排序过程中需要访问外存。 内部排序高速、有效,是我们比较常用的排序方法。外部排序速度慢,效率低,一般不建议使用外部排序,比较实用的排序还是只有内部排序。 2.内部排序分类:插入排序、选择排序、交换排序、归并排序、基数排序。 排序的分类大致为如下图: 在内部排序中,最常见、有效且实用的排序算是交换排序,本文将在下面章节重点讲述交换排序中的冒泡排序和快速排序。 Ⅲ、交换排序1.冒泡排序 冒牌排序是我们读书时最先接触的一种排序算法,也是比较经典的排序算法。 冒泡排序就是在要排序的一组数中,对当前还未排好序范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现 它们的排序与排序要求相反时,就将它们互换。 原始的冒泡排序函数: void bubbleSort(int a[], int n) { for(int i =0 ; i< n-1; ++i) { for(int j = 0; j < n-i-1; ++j) { if(a[j] > a[j+1]) { int tmp = a[j]; a[j] = a[j+1]; a[j+1] = tmp; } } } } 其实,原始的冒泡排序不是最后的算法,如果进行某一趟排序时并没有进行数据交换,则说明数据已经按要求排列好,可立即结束排序,避免不必要的比较过程。 对冒泡排序常见的改进方法是加入标志性变量,用于标志某一趟排序过程中是否有数据交换。 第1种改进法:设置一标志性变量pos,用于记录每趟排序中最后一次进行交换的位置。由于pos位置之后的记录均已交换到位,故在进行下一趟排序时只要扫描到pos位置即可。 void Bubble_1( int r[], int n) { int pos = 0; int i; int j; int tmp; i = n - 1; while(i > 0) { pos = 0; for(j=0; j<i; j++) { if(r[j] > r[j+1]) { pos = j; //记录交换的位置 tmp = r[j]; r[j] = r[j+1]; r[j+1] = tmp; } } i= pos; } } 第2种改进法:传统冒泡排序中每一趟排序操作只能找到一个最大值或最小值,我们考虑利用在每趟排序中进行正向和反向两遍冒泡的方法一次可以得到两个最终值(最大者和最小者) , 从而使 排序趟数几乎减少了一半。 void Bubble_2(int r[], int n) { int low = 0; int high= n -1; int tmp,j; while(low < high) { for(j=low; j<high; ++j) //正向冒泡,找到最大者 { if(r[j]> r[j+1]) { tmp = r[j]; r[j]=r[j+1]; r[j+1]=tmp; } --high; for(j=high; j>low; --j) //反向冒泡,找到最小者 { if(r[j]<r[j-1]) { tmp = r[j]; r[j]=r[j-1]; r[j-1]=tmp; } ++low; } } } } 2.快速排序 大致步骤如下: 1)选择一个基准元素,通常选择第一个元素或者最后一个元素。 2)通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的元素值比基准值大。 3)此时基准元素在其排好序后的正确位置。 4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。 举例: 对无序数组[6 2 4 1 5 9]排序: a),先把第一项[6]取出来, 用[6]依次与其余项进行比较: 如果比[6]小就放[6]前边,2 4 1 5都比[6]小,所以全部放到[6]前边; 如果比[6]大就放[6]后边,9比[6]大,放到[6]后边; 一趟排完后变成下边这样: 排序前 6 2 4 1 5 9 排序后 2 4 1 5 6 9 b),对前半边[2 4 1 5]继续进行快速排序 重复步骤a)后变成下边这样: 排序前 2 4 1 5 排序后 1 2 4 5 前半边排序完成,总的排序也完成: 排序前:[6 2 4 1 5 9] 排序后:[1 2 4 5 6 9] 排序结束 代码 将前后分开函数: int partition(int unsorted[], int low, int high) { int pivot = unsorted[low]; while(low < high) { while((low < high) && (unsorted[high] >= pivot)) --high; unsorted[low] = unsorted[high]; while((low < high) && (unsorted[low] <= pivot)) ++low; unsorted[high] = unsorted[low]; } unsorted[low] = pivot; return low; } 快速排序函数: void quickSort(int unsorted[], int low, int high) { int loc = 0; if(low < high) { loc = partition(unsorted, low, high); quickSort(unsorted, low, loc -1); quickSort(unsorted, loc + 1, high); } } 举例测试: void Main(void) { int i; int a[6] = {6, 2, 4, 1, 5, 9}; quickSort(a, 0, 5); for(i=0; i<6; i++) printf("a[%d] = a[%d]\n", i, a); } |
原文链接:http://bbs.elecfans.com/jishu_1569699_1_1.html
【转载】[经验] 嵌入式stm32实用的排序算法 - 交换排序的更多相关文章
- js实现两种实用的排序算法——冒泡、快速排序
分类:js (4443) (0) 零:数据准备,给定数组arr=[2,5,4,1,7,3,8,6,9,0]; 一:冒牌排序 1思想:冒泡排序思想:每一次对比相邻两个数据的大小,小的排在前面,如果前 ...
- 【转载】常见十大经典排序算法及C语言实现【附动图图解】
原文链接:https://www.cnblogs.com/onepixel/p/7674659.html 注意: 原文中的算法实现都是基于JS,本文全部修改为C实现,并且统一排序接口,另外增加了一些描 ...
- java排序算法-交换排序
public class ExchangeSortUtils { // 冒泡 public static void bubbleSort(int[] array) { int length = arr ...
- 排序算法——交换排序(冒泡排序、快速排序)(java)
一.冒泡排序 时间复杂度:O(n^2) 公认最慢的排序,每次把最大/最小的放一边,原理: [57,68,59,52] [57,68,59,52] [57,59,68,52] [57,59,52,68] ...
- Java排序 - 不实用的几个排序算法 -- 睡眠排序、猴子排序、面条排序、珠排序
介绍几个不实用的排序算法,一来可以在学习时增加一些乐趣,放松一下自己,二来可以学习一下.思考一下这些算法失败在哪里,又是否存在一些好的地方? 睡眠排序 这是一个思想比较简单,脑洞巨大的算法 -- 我们 ...
- Stooge排序与Bogo排序算法
本文地址:http://www.cnblogs.com/archimedes/p/stooge-bogo-sort-algorithm.html,转载请注明源地址. Stooge排序算法 Stooge ...
- 排序算法 2 qsort 库函数,泛型函数
_____谈谈排序算法 交换排序——>冒泡排序-->快速排序 选择排序——>简单选择排序——>堆排序 插入排序——>直接插入排序——>希尔排序 _____排序算法对 ...
- 排序算法 ----(转载::http://blog.csdn.net/hguisu/article/details/7776068)
1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表.即:先将序列的第1个记录看成是一个有序 ...
- 转载部长一篇大作:常用排序算法之JavaScript实现
转载部长一篇大作:常用排序算法之JavaScript实现 注:本文是转载实验室同门王部长的大作,找实习找工作在即,本文颇有用处!原文出处:http://www.cnblogs.com/ywang172 ...
随机推荐
- 分布式消息流平台:不要只想着Kafka,还有Pulsar
摘要:Pulsar作为一个云原生的分布式消息流平台,越来越频繁地出现在人们的视野中,大有替代Kafka江湖地位的趋势. 本文分享自华为云社区<MRS Pulsar:下一代分布式消息流平台全新发布 ...
- Raid(0/1/5/10)
一.Raid需要的硬盘数量 1.raid 0: 最少1块硬盘(但是1块盘没有意义,至少2块才有实际意义) 2.raid 1: 最少2块硬盘 3.raid 5: 最少3块硬盘 4 ...
- Spring AOP 事务配置(实现转账事务)
1. 事务特性 事务特性:ACID 原子性:整体 [原子性是指事务包含的所有操作要么全部成功,要么全部失败] 一致性:数据 [一个事务执行之前和执行之后都必须处于一致性状态] 隔离性:并发 [对于任意 ...
- 基于ECDHE的TLS握手流程
<!doctype html>3.3 基于ECDHE的TLS握手流程 html { overflow-x: initial !important } :root { --bg-color: ...
- Selenium系列4-元素定位
前言 说起元素定位,一定是学习自动化测试绕不开的第一道关,无论是web端的UI自动化还是移动端的自动化,在需要首先对元素进行定位才可以完成对元素的操作已达成测试目的,在Selenium中,可以使用fi ...
- 6步快速配置Tomcat环境变量(Win10)
一.配置 tomcat环境变量之前先安装jdk和配置jdk的环境变量 1.首先右击我的电脑(此电脑),点击属性,或者也可以从控制面板上打开,如下图,找到系统点击高级系统设置: 2.然后进入系统属性界面 ...
- find用法 以及和exec xargs 的组合使用
1.查找当前目录下所有的txt的文件 [root@master1 ~]# find . -name "*.txt" -type f ./a.txt ./b.txt 2.exec 结 ...
- 致Python初学者,Python常用的基础函数你知道有哪些吗?
Python基础函数: print()函数:打印字符串 raw_input()函数:从用户键盘捕获字符 len()函数:计算字符长度 format(12.3654,'6.2f'/'0.3%')函数:实 ...
- Nacos注册中心和配置中心流程原理
一.Nacos注册中心 1.服务启动后---->服务注册原理 springCloud集成Nacos实现原理: 服务启动时,在spring-cloud-commons包下 spring.facto ...
- win10系统移动热点使用技巧
win10系统是自动移动热点功能,在平时测试的时候,有时需要进行手机抓包,需要手机和电脑处于同一网络当中,这时可以开启热点使用. 如何开启移动热点? 直接搜索"移动热点" 但是如果 ...