冒泡排序及其算法优化分析

1.基本冒泡排序

冒泡排序的基本思想:假设被排序的记录数组d[1...N]垂直竖立,将每个记录d[i]看作是一个气泡,那么重的气泡就会向下下沉,轻的气泡就会向上升。每次都是相邻的两个气泡d[i]和d[i+1]进行比较。如果d[i]>d[i+1],那么就交换两个气泡,然后在比较d[i+1]和d[i+2],以此类推,知道所有的气泡都有序排列。假设排序20,37,11,42,29。

第1次冒泡:20。37,11,42,29    d[0]和d[1]比较
第2次冒泡:20,11,37,42,29    d[1]和d[2]比较
第3次冒泡:20,11,37,42,29    d[2]和d[3]比较
第4次冒泡:20,11,37,29,42    d[3]和d[4]比较

那么就找到了最重的气泡42,接下来按同样的方法找出第二重、第三重……的气泡,直到完成排序。根据以上分析可知需要双层循环。第一层循环控制次数,第二层循环控制要排序的数据范围。如下所示

第0次比较第0个到第n-1个,下标控制0~n-2
第1次比较第0个到第n-2个,下标控制0~n-3
.
.
第i次比较第0到第n-i+1个,下标控制0到n-i-2
.
.
第n-2次比较第0到第1个,下标控制0到0

冒泡排序算法的代码如下

int main(void)
{
    int i, j, tmp;
    int N = 5;
    int a[N] = {20,37,11,42,29};
    for( i=0; i<N; i++ ){
        for( j=0; j<N-i-1; j++ ){
            if( a[j]>a[j+1] ){
                tmp = a[j];
                a[j] = a[j+1];
                a[j+1] = tmp;
            }
        }
    }
    for(i=0; i<N; i++)
        printf("%d\n", a[i]);
    return 0;
 }

冒泡排序的最好、最坏、平均情况下的时间复杂度都是O(n^2)。但是若在某趟排序中未发现气泡位置的交换,则说明排序的无序区中所有的气泡均满足轻者在上,重者在下的原则,即为正序,则冒泡排序过程可在此次扫描后就终止。基于这种考虑,提出第一种改进算法

2.冒泡排序算法优化一:不做每次扫描都判断是否已经排序完成

如果在某趟循环中没有任何数据交换发生,则表明数据已经排序完成。那么剩余的循环就不需要再执行了。改进后的算法代码如下

int main(void)
{
    int i, j, tmp;
    int N = 5;
    int isSorted = 0;
    int a[5] = {20,37,11,42,29};
    for( i=0; i<N&&(!isSorted); i++ ){
    //只有在没有排序的情况下(!isSorted)才进行继续循环
        isSorted = 1;
        //设定排序标志
        for( j=0; j<N-i-1; j++ ){
            if( a[j]>a[j+1] ){
                isSorted = 0;
                //如果没有排序,就重新设定标志
                tmp = a[j];
                a[j] = a[j+1];
                a[j+1] = tmp;
            }
        }
    }
    for(i=0; i<N; i++)
        printf("%d\n", a[i]);
    return 0;
 }

这种排序方法,如果数据初始状态就是正序,那么扫描一趟就可以完成。所需要的比较和数据移动的次数分别时最小值n-1和0,也就是算法最好的时间复杂度是O(n);若初始数据反序,则需要进行n-1趟排序,每趟排序进行n-i次关键字的比较,且每次比较都必须移动数据三次来达到交换数据位置,这种情况下比较次数达到最大值n(n-1)/2,移动次数也达到最大值3n(n-1)/2,所以最坏的时间复杂度还是O(n^2)。平均的时间复杂度仍为O(n^2)

3.冒泡排序算法优化二:

     

借鉴 http://blog.chinaunix.net/uid-22744029-id-1770037.html

时间: 2024-12-28 21:34:25

冒泡排序及其算法优化分析的相关文章

算法优化分析---打印素数

1.针对 不同的代码,时间复杂度会有所不一样 时间复杂度:O(1),O(n),O(n^2) 2.for 循环一般最多使用2层,3层以上效率都很低 3.能使用for循环的地方尽量使用for循环,不要去使用while循环---while循环需要设计一个自增数count 算法优化实例比较:合数法求质数 原文地址:https://www.cnblogs.com/pengwa1226/p/10116915.html

各种排序算法的分析及java实现

各种排序算法的分析及java实现 排序一直以来都是让我很头疼的事,以前上<数据结构>打酱油去了,整个学期下来才勉强能写出个冒泡排序.由于下半年要准备工作了,也知道排序算法的重要性(据说是面试必问的知识点),所以又花了点时间重新研究了一下. 排序大的分类可以分为两种:内排序和外排序.在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序.下面讲的排序都是属于内排序. 内排序有可以分为以下几类: (1).插入排序:直接插入排序.二分法插入排序.希尔排序. (2).

SQL Server 聚合函数算法优化技巧

Sql server聚合函数在实际工作中应对各种需求使用的还是很广泛的,对于聚合函数的优化自然也就成为了一个重点,一个程序优化的好不好直接决定了这个程序的声明周期.Sql server聚合函数对一组值执行计算并返回单一的值.聚合函数对一组值执行计算,并返回单个值.除了 COUNT 以外,聚合函数都会忽略空值. 聚合函数经常与 SELECT 语句的 GROUP BY 子句一起使用. v1.写在前面 如果有对Sql server聚合函数不熟或者忘记了的可以看我之前的一片博客.sql server 基

性能优化——算法优化

背景 由于某种原因,我们系统需要记录另一个系统中一个表里的id.但是,当我们记录完了以后,别人系统可能会删除那个表里的一些数据,这样的话,我们这边就多了一些无效数据,所以,我们必须的找到这些无效的id,然后将其删除. 开始,我们的实现是这样:我们将记录下来的所有id放在一个list里,然后传到另一个系统,他将他们已经删除的id返回.具体处理代码如下: <pre name="code" class="java">public String findDele

深入浅出数据结构C语言版(17)——有关排序算法的分析

这一篇博文我们将讨论一些与排序算法有关的定理,这些定理将解释插入排序博文中提出的疑问(为什么冒泡排序与插入排序总是执行同样数量的交换操作,而选择排序不一定),同时为讲述高级排序算法做铺垫(高级排序为什么会更快). 在讨论相关定理之前,我们必须先掌握一个与顺序有关的概念:逆序数. 所谓逆序数,就是"逆序组合的个数",假设我们希望的顺序为从小到大(反之同理): 设有元素互异数列X0,X1,X2--Xn-1,(元素互异即数列中任取两数均不相等)从中任取两数作为组合(Xa,Xb),若a<

Swift 性能探索和优化分析

Swift 性能探索和优化分析 Apple 在推出 Swift 时就将其冠以先进,安全和高效的新一代编程语言之名.前两点在 Swift 的语法和语言特性中已经表现得淋漓尽致:像是尾随闭包,枚举关联值,可选值和强制的类型安全等都是 Swift 显而易见的优点.但是对于高效一点,就没有那么明显了.在 2014 年 WWDC 大会上 Apple 宣称 Swift 具有超越 Objective-C 的性能,甚至某些情况下可以媲美和超过 C.但是在 Swift 正式发布后,很多开发者发现似乎 Swift

算法优化之车牌识别---车牌识别优化项

基于DM6437的车牌识别算法移植及优化 http://cdmd.cnki.com.cn/Article/CDMD-10701-1013114119.htm 5.1 车牌识别算法的移植52-54 5.1.1 车牌识别算法工程的创建52 5.1.2 算法的编译及调试52-53 5.1.3 算法的测试53-54 5.2 车牌程序设计54-55 5.2.1 图像采集和显示54 5.2.2 数据处理54-55 5.3 DSP算法优化概述55-59 5.3.1 DSP算法优化思想55-59 5.4 车牌识

【常用算法思路分析系列】排序高频题集

最近在牛客上整理常用的一些算法思路,[常用算法思路分析系列]主要是针对一些高频算法笔试.面试题目的解题思路进行总结,大部分也给出了具体的代码实现,本篇文章是对排序相关题目的思路分析. 1.简单分类 首先对一些常用算法按空间复杂度进行分类如下: O(1): 冒泡排序.选择排序.插入排序.希尔排序.堆排序 O(logN)~O(N): 快速排序 O(N): 归并排序 O(M): 计数排序.基数排序 2.对一个基本有序的有序的数组排序,选择哪种排序算法? 基本有序:指如果把数组排好序的话,每个元素移动的

[转]各种排序算法的分析及java实现

原文:http://www.cnblogs.com/liuling/p/2013-7-24-01.html 排序一直以来都是让我很头疼的事,以前上<数据结构>打酱油去了,整个学期下来才勉强能写出个冒泡排序.由于下半年要准备工作了,也知道排序算法的重要性(据说是面试必问的知识点),所以又花了点时间重新研究了一下. 排序大的分类可以分为两种:内排序和外排序.在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序.下面讲的排序都是属于内排序. 内排序有可以分为以下几