排序算法—冒泡排序

*/-->

排序算法—冒泡排序

Table of Contents

  • 1 问题描述
  • 2 冒泡排序(Bubble)
    • 2.1 冒泡排序(一)
    • 2.2 冒泡排序(二)
    • 2.3 冒泡排序(三)
    • 2.4 冒泡排序(四)
  • 3 阅读参考

1 问题描述

引子

排序是数据结构中十分重要的一章,排序算法有很多种,一直没时间整理而且很多排序算法理解的也不是很透彻.希望通过这次整理吃透吧! 排序算法十分多,故分篇进行整理.

说明

本文重点是理解排序算法,而不是完整的程序,所以每节都只有具体排序算法的接口.没有完整的源代码.

分类
内部排序
整个排序过程完全在内存中进行.
外部排序
因为待排序的记录数据太大,内存无法容纳全部数据,需要借助外部存储设备才能完成排序.

2 冒泡排序(Bubble)

这个应该是众多程序员接触的第一个排序算法,十分基础.

冒泡排序算法的原理如下:

每次比较相邻的元素,如果第一个数比第二个数大,就交换他们.对每一对相邻元素做同样的工作,

从开始第一对到最后一对.这步做完后,最后的元素就是最大的数.重复上述步骤,这样第 i 次比较完后,

最后的元素就是第 i 大的数.持续每次对越来越少的元素重复上面的步骤,直到没有需要比较的元素为止.

2.1 冒泡排序(一)

 1:  /**
 2:    * 基本的冒泡排序
 3:    * @param int* num 排序数组
 4:    * @param int length 数组大小
 5:    * @return int 排序成功与否
 6:    */
 7:  int BubbleSort(int *num, int length)
 8:  {
 9:     int i,j;
10:     if(length < 2)
11:        return 0;
12:     for(i = 0; i < n; i++)           //外层循环控制排序的趟数
13:     {
14:        for(j = 0; j < n-1-i; j++)    //内层循环控制排序要交换的数的范围
15:        {
16:           if(num[j] > num[j+1])
17:              swap(num[j],num[j+1])   //两两相邻的数比较大小
18:        }
19:     }
20:     return 0;
21:  }
22:  算法分析:
23:    时间复杂度:最优的情况,所有的数都是有序的,那么内层循环就不用交换数了,
24:                      只进行外层的循环,复杂度是O(n);
25:             最差的情况,所有的数都是倒序的,那么两层循环都要进行,复杂度是O(n^2);
26:             平均时间复杂度是O(n^2);
27:      空间复杂度:一维数组 O(1);

该思路也可以逆序进行,伪代码如下:

 1:  for(i from n-1 downto 0)
 2:  {
 3:     for(j from n-1 downto n-1-i)
 4:     {
 5:        cmp(num[j],num[j-1])
 6:     }
 7:  }
 8:
 9:  // 其他类似的写法还有:
10:  for(i = n-1; i > 0; i--)
11:  {
12:     for(j = 0; j > i; j++)
13:     {
14:        cmp(j,j+1)
15:     }
16:  }
17:
18:  // 交换排序
19:  for(i = 0; i < n-1; i++)
20:  {
21:     for(j = i+1; j < n; j++)
22:     {
23:        cmp(num[i],num[j])   //此时比较的不是相邻的两个元素了
24:     }
25:  }

2.2 冒泡排序(二)

上述的排序是两两相邻的数进行比较,更符合冒泡的形态.但实际上要比较的也不一定就是相邻的数.

 1:    /**
 2:    * 改进的冒泡排序一
 3:    * @param int* num 排序数组
 4:    * @param int length 数组大小
 5:    * @return int 排序成功与否
 6:    */
 7:
 8:  //逆序版 但还是不同的较少了交换的次数 而且类似选择排序
 9:  int BubbleSort(int *num, int length)
10:  {
11:     int i,j,max;
12:     if(length < 2)
13:        return 0;
14:     for(i = n-1; i > 0; i--)           //外层循环控制排序的趟数
15:     {
16:        for(j = 1,max = 0; j < i; j++)  //从0~j左边部分选出最大的数
17:        {
18:           if(num[max] < num[j])
19:             max = j;
20:        }
21:        if(num[i] < num[max])
22:          swap(num[i],num[max]);
23:     }
24:     return 0;
25:  }

2.3 冒泡排序(三)

可以设置一个标志,如果一趟过程中发成了交换,则为true,反之则未false,如果有一趟没有发生交换就说明排序已经完成

 1:  /**
 2:    * 改进的冒泡排序二
 3:    * @param int* num 排序数组
 4:    * @param int length 数组大小
 5:    * @return int 排序成功与否
 6:    */
 7:  int BubbleSort(int *num, int length)
 8:  {
 9:     int i,j,flag;
10:     if(length < 2)
11:        return 0;
12:     for(i = 0; i < n-1; i++)       //外层循环控制排序的趟数
13:     {
14:        flag = 0;
15:        for(j = n-1; j > i; i++)    //内层循环控制依次排序的完成
16:        {
17:           if(num[j] > num[j-1])
18:           {
19:             swap(num[i],num[j])
20:             flag = 1;
21:           }
22:        }
23:        if(flag == 0)               //终止排序
24:          break;
25:     }
26:        return 0;
27:  }
28:  如果100个数,就前10个数是乱序的,后面的数是有序的.可以通过设置标志记录交换时的位置,下一次循环到此处即可.
29:  int BubbleSort(int *num, int length)
30:  {
31:     int i,j,lastchange;            //lastchange记录上次交换的位置
32:     if(length < 2)
33:        return 0;
34:     i = n;
35:     while(i > 0)
36:     {
37:       lastchange = 0;
38:       for(j = 0; j < i; j++)
39:       {
40:          if(num[j] > num[j+1])
41:          {
42:             swap(num[j],num[j+1])
43:             lastchagne = j;
44:          } //if
45:       }// for
46:       i = lastchange;
47:     }
48:        return 0;
49:  }

2.4 冒泡排序(四)

双向冒泡进一步提高效率,又称鸡尾酒排序.

 1:   /**
 2:  * 基本的冒泡排序
 3:  * @param int* num 排序数组
 4:  * @param int length 数组大小
 5:  * @return int 排序成功与否
 6:  */
 7:  int BubbleSort(int *num, int length)
 8:  {
 9:     int i,j,left,right,l,r;
10:     left = 0;i = 0;
11:     right = length-1;
12:
13:     //双向冒泡
14:     while(left < right)
15:     {
16:     //必须要给l和r赋值,否则若数组一开始就是有序,则right = r时,r未赋值会报错.
17:       l = left + 1;
18:       r = right - 1;
19:
20:       // 第一次循环将最大的值放到末尾
21:       for(j = left; j < right; j++)
22:       {
23:          if(a[j] > a[j+1])
24:          {
25:             swap(a[j],a[j+1]);
26:             r = j;
27:          }
28:       }
29:       right = r;  // 这里好好想想,r 不一定是最后一个数喔!
30:
31:      //第二次循环将最小的值放到开头
32:       for(j = right; j > left; j--)
33:       {
34:         if(a[j] < a[j-1])
35:         {
36:            swap(a[j],a[j-1]);
37:            l = j;
38:         }
39:       }
40:       left = l;
41:
42:       //测试结果
43:       /*
44:        printf("第%d次排序结果:",i+1);
45:        i++;
46:        for(j = 0; j < n; j++)
47:         printf("%d\t",a[j]);
48:       */
49:     }
50:  }
51:

3 阅读参考

双向优化

初步优化例子

视频演示版

冒泡排序之wiki

Date: 2014-08-15 Fri

Author: Chen Jingran

Org version 7.8.11 with Emacs version 24

Validate XHTML 1.0

排序算法—冒泡排序,布布扣,bubuko.com

时间: 2024-09-30 16:54:56

排序算法—冒泡排序的相关文章

经典排序算法 - 冒泡排序Bubble sort

 原文出自于 http://www.cnblogs.com/kkun/archive/2011/11/23/bubble_sort.html 经典排序算法 - 冒泡排序Bubble sort 原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子 例子为从小到大排序, 原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 | 第一趟排序(外循环) 第

C语言中的排序算法--冒泡排序,选择排序,希尔排序

冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端 维基百科:点击打开链接 [cpp] view plain copy /* 用选择法对10个数进行排序 */ #include<stdio.h> void main() { int i,j,

排序算法-冒泡排序(改),选择排序

上次说冒泡排序留下2个问题,一个是选择排序,一个是冒泡排序性能,这次会先说选择排序,然后说冒泡排序的优化 一选择排序 选择排序是一种简单直观的排序算法.它的工作原理是每一次从待排序的元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 流程: (有小到大排序) 第一轮 将0位元素与后续所有元素比较,将小的元素放在0位 第二轮 将1位元素与后续所有元素比较,将小的元素放在1位 ... 直到最后一位 代码上次已经贴出,这里复制下 1 public static vo

算法 排序算法--冒泡排序

冒泡排序是排序算法的一种,思路清晰,代码简洁,常被用在大学生计算机课程中. “冒泡”这个名字的由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端,故名. 这里以从小到大排序为例进行讲解. 基本思想及举例说明 冒泡排序的基本思想就是不断比较相邻的两个数,让较大的元素不断地往后移.经过一轮比较,就选出最大的数:经过第2轮比较,就选出次大的数,以此类推. 下面以对 3  2  4  1 进行冒泡排序说明. 第一轮 排序过程3  2  4  1    (最初)2  3  4  2    (比较3和2,

排序算法(冒泡排序,选择排序,插入排序,快速排序)

数组的排序算法 选择排序 每次选择所要排序得数组中的最大值(由大到小排序,由小到大排序则选择最小值)的数组元素,将这个数组元组的值与最前面没有排序的数组元素进行交换, 第一次排序之后,最大的数字来到了第一位,再从第二个元素开始找,找到最大的元素,与第二个交换位置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <std

排序算法—冒泡排序算法

冒泡介绍 算法原理 算法分析 算法实现 例子 一.冒泡介绍 名称:冒泡排序: 英文:Bubble Sort 时间复杂度:O(n2) 算法稳定性:稳定排序算法: 实质:把小(大)的元素往前(后)调 #冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法. #它重复地走访过要排序的元素列,一次比较两个相邻的元素,如果他们的顺序(如从大到小.首字母从A到Z)错误就把他们交换过来.走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素已经排序完成. #这个算法的名字由来

java的八种排序算法---冒泡排序

冒泡排序是一种简单的排序算法,它重复的走访要排序的数列,两两比较相邻的元素,如果左边的大于右边就把他们交换过来,以此类推重复的排序,直到没有要排序的数列为止,这个算法的由来是因为越小的数列随着排序会慢慢的浮到数列顶端. /** * 冒泡排序 * 比较相邻的元素.如果第一个比第二个大,就交换他们两个. * 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数. * 针对所有的元素重复以上的步骤,除了最后一个. * 持续每次对越来越少的元素重复上面的步骤,

排序算法--冒泡排序(一)

# 冒泡排序 冒泡排序(Bubble Sort)也是一种简单直观的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端. 作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉.冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍

吴裕雄--天生自然数据结构:十大经典排序算法——冒泡排序

冒泡排序 冒泡排序(Bubble Sort)也是一种简单直观的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端. 作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉.冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中