【转载】[经验] 嵌入式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 ...
随机推荐
- Servlet学习笔记(一)之Servlet原理、初始化、生命周期、结构体系
Servlet是用java语言编写的应用到Web服务器端的扩展技术,与java对象的区别是,Servlet对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器的支持(以下会介绍原因, ...
- rsync 服务搭建
rsync 服务搭建 服务端部署操作内容: 创建rsync用户和用户组 eg: useradd -s /sbin/nologin -M rsync 创建需要备份的指定目录,并修改权限 eg: mkdi ...
- APT组织跟踪与溯源
前言 在攻防演练中,高质量的蓝队报告往往需要溯源到攻击团队.国内黑产犯罪团伙.国外APT攻击. 红队现阶段对自己的信息保护的往往较好,根据以往溯源成功案例来看还是通过前端js获取用户ID信息.mysq ...
- IPSec协议框架
文章目录 1. IPSec简介 1.1 起源 1.2 定义 1.3 受益 2. IPSec原理描述 2.1 IPSec协议框架 2.1.1 安全联盟 2.1.2 安全协议 报文头结构 2.1.3 封装 ...
- js 显示日期时间,时间过一秒加1
html: <div id="data"><font>2017年10月17日 15:11:11</font></span> js: ...
- Linux上安装服务器监视工具,名为Scout_Realtime。
如何从浏览器监视Linux服务器和进程指标 在服务器上安装Ruby 1.9.3+ sudo yum -y install rubygems-devel 在Linux系统上安装了Ruby之后,现在可以使 ...
- (未完)Java集合框架梳理(基于JDK1.8)
Java集合类主要由两个接口Collection和Map派生出来的,Collection派生出了三个子接口:List.Set.Queue(Java5新增的队列),因此Java集合大致也可分成List. ...
- minix3使用轻快入门
minix3是一款迷你的unix作业系统,但又不在at&t代码的基础上构建.当年开发这款作业系统的作者仅仅是拿来自用,给学生上课使用的. 如果你已经安装了minix3,你还需要安装openss ...
- 对javaEE Tutorial上hello2的源码分析详解
首先: java EE 上的hello2项目是一个部署在glass fish上的开发源码的java web项目,在终端通过命令行使用maven进行打包成.war文件,最后部署到相关的glass fis ...
- PHP设计模式之原型模式
原型模式其实更形象的来说应该叫克隆模式.它主要的行为是对对象进行克隆,但是又把被克隆的对象称之为最初的原型,于是,这个模式就这样被命名了.说真的,从使用方式来看真的感觉叫克隆模式更贴切一些. Gof类 ...