`
chenzehe
  • 浏览: 532582 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

冒泡排序算法分析及程序示例

阅读更多
实例说明

  用冒泡排序方法对数组进行排序。

实例解析

  交换排序的基本思想是两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。

  应用交换排序基本思想的主要排序方法有冒泡排序和快速排序。

冒泡排序

  将被排序的记录数组 R[1..n] 垂直排列,每个记录 R[i] 看做是重量为 R[i].key 的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组 R 。凡扫描到违反本原则的轻气泡,就使其向上“漂浮”。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。

  (1) 初始, R[1..n] 为无序区。

  (2) 第一趟扫描,从无序区底部向上依次比较相邻的两个气泡的重量,若发现轻者在下、重者在上,则交换二者的位置。即依次比较 (R[n],R[n-1]) 、 (R[n-1],R[n-2]) 、 … 、 (R[2],R[1]); 对于每对气泡 (R[j+1],R[j]), 若 R[j+1].key<R[j].key, 则交换 R[j+1] 和 R[j] 的内容。

  第一趟扫描完毕时,“最轻”的气泡就飘浮到该区间的顶部,即关键字最小的记录被放在最高位置 R[1] 上。

  (3) 第二趟扫描,扫描 R[2..n]。扫描完毕时,“次轻”的气泡飘浮到 R[2] 的位置上 …… 最后,经过 n-1 趟扫描可得到有序区 R[1..n]。

  注意:第 i 趟扫描时, R[1..i-1] 和 R[i..n] 分别为当前的有序区和无序区。扫描仍是从无序区底部向上直至该区顶部。扫描完毕时,该区中最轻气泡漂浮到顶部位置 R[i] 上,结果是 R[1..i] 变为新的有序区。

冒泡排序算法

  因为每一趟排序都使有序区增加了一个气泡,在经过 n-1 趟排序之后,有序区中就有 n-1 个气泡,而无序区中气泡的重量总是大于等于有序区中气泡的重量,所以整个冒泡排序过程至多需要进行 n-1 趟排序。

  若在某一趟排序中未发现气泡位置的交换,则说明待排序的无序区中所有气泡均满足轻者在上,重者在下的原则,因此,冒泡排序过程可在此趟排序后终止。为此,在下面给出的算法中,引入一个布尔量 exchange, 在每趟排序开始前,先将其置为 FALSE 。若排序过程中发生了交换,则将其置为 TRUE 。各趟排序结束时检查 exchange, 若未曾发生过交换则终止算法,不再进行下趟排序。

具体算法如下:

void BubbleSort(SeqList R){
  //R(1..n) 是待排序的文件,采用自下向上扫描,对 R 做冒泡排序
  int i,j;
  Boolean exchange; // 交换标志
  for(i=1;i<n;i++){ // 最多做 n-1 趟排序
    exchange=FALSE; // 本趟排序开始前,交换标志应为假
    for(j=n-1;j>=i;j--) // 对当前无序区 R[i..n] 自下向上扫描
      if(R[j+1].key<R[j].key){ // 交换记录
        R[0]=R[j+1]; //R[0] 不是哨兵,仅做暂存单元
        R[j+1]=R[j];
        R[j]=R[0];
        exchange=TRUE; // 发生了交换,故将交换标志置为真
      }
    if(!exchange) // 本趟排序未发生交换,提前终止算法
      return;
  } //endfor( 外循环 )
}//BubbleSort

程序代码—冒泡排序

#include <stdio.h>
#define MAX 255
int R[MAX];

void Bubble_Sort(int n){
   /*R(1..n) 是待排序的文件,采用自下向上扫描,对 R 做冒泡排序 */
   int i,j;
   int exchange; /* 交换标志 */
   for(i=1;i<n;i++){ /* 最多做 n-1 趟排序 */
      exchange=0; /* 本趟排序开始前,交换标志应为假 */
      for(j=n-1;j>=i;j--) /* 对当前无序区 R[i..n] 自下向上扫描 */
         if(R[j+1]<R[j]){ /* 交换记录 */
            R[0]=R[j+1]; /* R[0] 不是哨兵,仅做暂存单元 */
            R[j+1]=R[j];
            R[j]=R[0];
            exchange=1; /* 发生了交换,故将交换标志置为真 */
         }
      if(!exchange) /* 本趟排序未发生交换,提前终止算法 */
         return;
   }
}

void main(){
   int i,n;
   clrscr();
   puts("Please input total element number of the sequence:");
   scanf("%d",&n);
   if(n<=0 || n>MAX){
      printf("n must more than 0 and less than %d.\n",MAX);
      exit(0);
   }
   puts("Please input the elements one by one:");
   for(i=1;i<=n;i++)
      scanf("%d",&R[i]);
   puts("The sequence you input is:");
   for(i=1;i<=n;i++)
      printf("%4d",R[i]);
   Bubble_Sort(n);
   puts("\nThe sequence after bubble_sort is:");
   for(i=1;i<=n;i++)
      printf("%4d",R[i]);
   puts("\n Press any key to quit…");
   getch();
}

归纳注释

  算法的最好时间复杂度: 若文件的初始状态是正序的, 一趟扫描即可完成排序。所需的关键字比较次数 C 和记录移动次数 M 均达到最小值,即 C(min)=n-1, M(min)= 0 。冒泡排序最好的时间复杂度为 O(n)。

  算法的最坏时间复杂度: 若初始文件是反序的,需要进行 n-1 趟排序。每趟排序要进行 n-1 次关键字的比较 (1<=i<=n-1), 且每次比较都必须移动记录 3 次。在这种情况下,比较和移动次数均达到最大值,即 C(max)=n(n-1)/2=O(n ^2 ),M(max)=3n(n-1)/2=O(n ^2 )。冒泡排序的最坏时间复杂度为 O(n^2 )。

  算法的平均时间复杂度为 O(n^2 )。虽然冒泡排序不一定要进行 n-1 趟,但由于它的记录移动次数较多,故平均时间性能比直接插入排序要差得多。

  算法稳定性:冒泡排序是就地排序,且它是稳定的。

  算法改进:上述的冒泡排序还可做如下的改进,① 记住最后一次交换发生位置 lastExchange 的冒泡排序( 该位置之前的相邻记录均已有序 )。下一趟排序开始时,R[1..lastExchange-1] 是有序区, R[lastExchange..n] 是无序区。这样,一趟排序可能使当前有序区扩充多个记录,从而减少排序的趟数。② 改变扫描方向的冒泡排序。冒泡排序具有不对称性。能一趟扫描完成排序的情况,只有最轻的气泡位于 R[n] 的位置,其余的气泡均已排好序,那么也只需一趟扫描就可以完成排序。如对初始关键字序列 12、18、42、44、45、67、94、10 就仅需一趟扫描。需要 n-1 趟扫描完成排序情况,当只有最重的气泡位于 R[1] 的位置,其余的气泡均已排好序时,则仍需做 n-1 趟扫描才能完成排序。比如对初始关键字序列:94、10、12、18、42、44、45、67 就需 7 趟扫描。造成不对称性的原因是每趟扫描仅能使最重气泡“下沉”一个位置,因此使位于顶端的最重气泡下沉到底部时,需做 n-1 趟扫描。在排序过程中交替改变扫描方向,可改进不对称性。
分享到:
评论

相关推荐

    数据结构与算法程序示例。常用算法思想总结归档。使知识体系化.zip

    算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...

    数据结构与排序算法------通过代码示例,讲解:数据结构和9种排序算法。.zip

    算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...

    PHP四种基本排序算法示例

    但是对于基本的排序算法还是应该掌握的,它是程序开发的必备工具。这里介绍冒泡排序,插入排序,选择排序,快速排序四种基本算法,分析一下算法的思路。 前提:分别用冒泡排序法,快速排序法,选择排序法,插入排序...

    算法:算法C语言实现 第1-4部分 基础知识、数据结构、排序及搜索

     2.6 算法分析示例  2.7 保证、预测及局限性 第二部分 数据结构  第3章 基本数据结构  3.1 构建组件  3.2 数组  3.3 链表  3.4 链表的基本处理操作  3.5 链表的内存分配  3.6 字符串  3.7 复合...

    基于java语言的数据结构及算法实现,LeetCode算法示例.zip

    算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...

    C/C++常用算法手册.秦姣华(有详细书签).rar

    4.2.2 冒泡排序算法示例 102 4.3 选择排序法 104 4.3.1 选择排序算法 104 4.3.2 选择排序算法示例 105 4.4 插入排序法 107 4.4.1 插入排序算法 107 4.4.2 插入排序算法示例 108 4.5 Shell排序法 110 4.5.1 ...

    数据结构与算法示例.zip

    算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...

    学习数据结构与算法的代码示例,目前提供 Java、Python、Go、C++ 多种语言支持。.zip

    算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...

    CS-261-Assignment-1:各种排序算法的示例

    CS-261-Assignment-1 ...作业说明:这项作业是为了对algorihms类进行分析,因此,按预期,第一个作业是对4种不同的排序算法(例如合并排序和冒泡排序)进行最终化。 用c编写的4种不同的排序程序。 程序示例运行:

    Java 核心类的示例、 部分工具类、 数据结构和算法.zip

    算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...

    《C算法》((美国)Robert Sedgewick)清晰版[DJVU] 第一卷

    4.3 栈ADT客户程序示例 99 练习 104 4.4 栈ADT实现 105 练习 108 4.5 创建新ADT 109 练习 111 4.6 FIFO队列及广义队列 111 练习 117 4.7 重复项和索引项 118 练习 121 4.8 一级ADT 122 练习 130 4.9 ADT应用示例 131...

    《C算法》((美国)Robert Sedgewick)清晰版[DJVU] 第二卷

    4.3 栈ADT客户程序示例 99 练习 104 4.4 栈ADT实现 105 练习 108 4.5 创建新ADT 109 练习 111 4.6 FIFO队列及广义队列 111 练习 117 4.7 重复项和索引项 118 练习 121 4.8 一级ADT 122 练习 130 4.9 ADT应用示例 131...

    数据结构习题答案(全部算法)严蔚敏版

    6.7 二叉树的建立和遍历C语言源程序示例 习题六 第7章 图 7.1 图的基本概念和术语 7.1.1 图的基本概念 7.1.2 路径和回路 7.1.3 连通图 7.1.4 顶点的度 7.2 图的存储结构 7.2.1 邻接矩阵 7.2.2 邻接链表 ...

    数据结构与算法:语言描述(中英文)

    第3章是对基础排序算法的介绍,例如冒泡排序和插入排序。而第4章则研究了用于内存查找的最基本算法,顺序查找和二叉查找。 第5章探讨了两种经典的数据结构:堆栈和队列。本章节强调的重点是这些数据结构在解决日常...

    并行计算导论(原书第2版).[美]Ananth Grama(带详细书签).pdf

    9.3 冒泡排序及其变体 9.3.1 奇偶转换 9.3.2 希尔排序 9.4 快速排序 9.4.1 并行快速排序 9.4.2 用于CRCWPRAM的并行形式 9.4.3 用于实际体系结构的并行形式 9.4.4 主元选择 9.5 桶和样本排序 9.6 其他排序...

    最新Python3.5零基础+高级+完整项目(28周全)培训视频学习资料

    最新Python3.5零基础+高级+完整项目(28周全)培训视频学习资料;本资料仅用于学习。 【课程内容】 ...冒泡 选择 插入排序 快排 堆排序 第28周 堆排序复习 归并排序 希尔排序 算法练习 栈和队列 数据结构其他

    ASP.NET常见问题集锦.zip

    C#排序算法大全.txt C#编程规范.doc C#语言参考.doc Code.doc C#中的“装箱”与“拆箱”.txt Datagrid分页、排序、删除代码.txt DataList分页、增加、删除、修改实例.doc is as override示例.txt JA_ASP ...

    java自学之道

    3.2冒泡排序算法 3.3 快速排序算法 3.4选择排序算法 3.5直接插入算法 3.6希尔排序算法 3.7 二分查找算法 3.8 二叉树 3.9 图的实现 3.10 生产者消费者的实现 3.11 银行家算法 3.12 KMP算法 3.13 RSA的实现 第4章 IO流...

    java基础案例与开发详解案例源码全

    4.4.1 算法-冒泡排序113 4.4.2 插入排序115 4.5 增强for循环116 4.6 本章练习117 第5章 5.1 面向过程的设计思想120 5.2 面向对象的设计思想120 5.3 抽象121 5.3.1 对象的理解121 5.3.2 Java抽象思想的实现122 5.4 ...

Global site tag (gtag.js) - Google Analytics