什么是冒泡法?[详细的讲下]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是冒泡法?[详细的讲下]相关的知识,希望对你有一定的参考价值。

参考技术A 冒泡排序   冒泡排序:BubbleSort
  基本概念
  冒泡排序的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复以上过程,仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再大于第2个数),将小数放前,大数放后,一直比较到最小数前的一对相邻数,将小数放前,大数放后,第二趟结束,在倒数第二个数中得到一个新的最小数。如此下去,直至最终完成排序。
  由于在排序过程中总是小数往前放,大数往后放,相当于气泡往上升,所以称作冒泡排序。
  用二重循环实现,外循环变量设为i,内循环变量设为j。外循环重复9次,内循环依次重复9,8,...,1次。每次进行比较的两个元素都是与内循环j有关的,它们可以分别用a[j]和a[j+1]标识,i的值依次为1,2,...,9,对于每一个i, j的值依次为1,2,...10-i。
  产生
  在许多程序设计中,我们需要将一个数列进行排序,以方便统计,常见的排序方法有冒泡排序,二叉树排序,选择排序等等。而冒泡排序一直由于其简洁的思想方法和比较高的效率而倍受青睐。
  排序过程
  设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气泡,根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R,凡扫描到违反本原则的轻气泡,就使其向上"漂浮",如此反复进行,直至最后任何两个气泡都是轻者在上,重者在下为止。
  算法示例
  49 13 13 13 13 13 13 13
  38 49 27 27 27 27 27 27
  65 38 49 38 38 38 38 38
  97 65 38 49 49 49 49 49
  76 97 65 49 49 49 49 49
  13 76 97 65 65 65 65 65
  27 27 76 97 76 76 76 76
  49 49 49 76 97 97 97 97
  Procedure BubbleSort(Var R : FileType) //从下往上扫描的起泡排序//
  Begin
  For I := 1 To N-1 Do //做N-1趟排序//
  begin
  NoSwap := True; //置未排序的标志//
  For J := N - 1 DownTo 1 Do //从底部往上扫描//
  begin
  If R[J+1]< R[J] Then //交换元素//
  begin
  Temp := R[J+1]; R[J+1 := R[J]; R[J] := Temp;
  NoSwap := False
  end;
  end;
  If NoSwap Then Return//本趟排序中未发生交换,则终止算法//
  end
  End; //BubbleSort//
  该算法的时间复杂性为O(n2),算法为稳定的排序方
  冒泡排序c++代码
  #include <iostream.h>
  void BubbleSort(int* pData,int Count)
  
  int iTemp;
  for(int i=1;i<Count;i++)
  
  for(int j=Count-1;j>=i;j--)
  
  if(pData[j]<pData[j-1])
  
  iTemp = pData[j-1];
  pData[j-1] = pData[j];
  pData[j] = iTemp;
  
  
  
  
  void main()
  
  int data[] = 10,9,8,7,6,5,4;
  BubbleSort(data,7);
  for (int i=0;i<7;i++)
  cout<<data[i]<<" ";
  cout<<"\n";
  
  冒泡排序Ruby代码
  def bubble(arr)
  (arr.length-1).downto(1) do |j|
  a1 = arr.dup
  j.times do |i|
  if arr > arr[i+1]
  arr,arr[i+1] = arr[i+1],arr
  end
  end
  break if a1 == arr
  end
  arr
  end
  冒泡排序Java代码
  static void BubbleSort(int a [])
  int temp=0;
  for (int i = 0; i < a.length ; i++)
  for (int j = 0; j < a.length - i - 1; j++)
  if (a[j]>a[j + 1]) //把这里改成大于,就是升序了
  temp=a[j];
  a[j]=a[j + 1];
  a[j + 1]=temp;
  
  
  
  
  冒泡排序Visual Basic代码
  Option Explicit
  Private Sub Form_click()
  Dim a, c As Variant
  Dim i As Integer, temp As Integer, w As Integer
  a = Array(12, 45, 17, 80, 50)
  For i = 0 To UBound(a) - 1
  If (a(i) > a(i + 1)) Then '若是递减,改为a(i)<a(i+1)
  temp = a(i)
  a(i) = a(i + 1)
  a(i + 1) = temp
  End If
  Next
  For Each c In a
  Print c;
  Next
  End Sub
  冒泡排序Pascal代码
  <i id="bks_9tjbxut2">program bubblesort;
  const
  N=20;
  MAX=10;
  var
  a:array[1..N] of 1..MAX;
  temp,i,j:integer;
  begin
  randomize;
  for i:=1 to N do a:=1+random(MAX);
  writeln('Array before sorted:');
  for i:=1 to N do write(a,' ');
  writeln;
  for i:=N-1 downto 1 do
  for j:=1 to i do
  if a[j]<a[j+1] then
  begin
  temp:=a[j];
  a[j]:=a[j+1];
  a[j+1]:=temp
  end;
  writeln('Array sorted:');
  for i:=1 to N do write(a,' ');
  writeln;
  writeln('End sorted.');
  readln;
  end.
  冒泡排序C#代码
  public void BubbleSort(int[] array)
  int length = array.Length;
  for (int i = 0; i <= length - 2; i++)
  for (int j = length - 1; j >= 1; j--)
  if (array[j] < array[j - 1] )
  int temp = array[j];
  array[j] = array[j - 1];
  array[j - 1] = temp;
  
  
  
  
  冒泡排序Python代码
  #algo
  def bubble(list):
  count = len(list) -1
  while count > 0 :
  i = 0
  onceflag = True
  while i < count :
  if int(list) > int(list[i+1]) :
  tmp = list
  list = list [i+1]
  list[i+1] =tmp
  onceflag = False
  i = i + 1
  if onceflag : return list
  count = count - 1
  return list
  #test
  li = [1,9,8,5,4,3,6,7,0,2]
  print bubble(li)
  冒泡排序法的改进
  比如用冒泡排序将4、5、7、1、2、3这6个数排序。在该列中,第二趟排序结束后,数组已排好序,但计算机此时并不知道已经反排好序,计算机还需要进行一趟比较,如果这一趟比较,未发生任何数据交换,则知道已排序好,可以不再进行比较了。因而第三趟比较还需要进行,但第四、五趟比较则是不必要的。为此,我们可以考虑程序的优化。
  为了标志在比较中是否进行了,设一个布尔量flag。在进行每趟比较前将flag置成true。如果在比较中发生了数据交换,则将flag置为false,在一趟比较结束后,再判断flag,如果它仍为true(表明在该趟比较中未发生一次数据交换)则结束排序,否则进行下一趟比较。
  性能分析
  若记录序列的初始状态为"正序",则冒泡排序过程只需进行一趟排序,在排序过程中只需进行n-1次比较,且不移动记录;反之,若记录序列的初始状态为"逆序",则需进行n(n-1)/2次比较和记录移动。因此冒泡排序总的时间复杂度为O(n*n)。
参考技术B 简单的给你说下,比如说有一个数列,要用冒泡法由大到小排序那么你就用第一个数,去和这列数的每一个分别去做比较,如果有比这个数大的就让两数对掉,直到比较完这个数列,此时第一个数就是最大的,然后用第二个数在去和整列数比较,当然这时就不包括第一个数了,因为第一个数已经是最大的了。。如此反复直到整列数排列完 参考技术C 想必您课本上都有例子了, 思想就是从数组的第一个元素一个一个跟后面的比较,把它挪到它应该在的位置。用两个循环来控制。 参考技术D http://baike.baidu.com/view/254413.htm百度百科有详细解释,如果还不明白,请追问

算法之旅 | 冒泡排序法

HTML5学堂-码匠:本期继续走入算法 —— 冒泡排序法。冒泡排序算法相对简单,容易上手,稳定性也比较高,
算是一种较好理解的算法,也是面试官高频提问的算法之一。

Tips:关于“算法”及“排序”的基础知识,在此前“选择排序法”中已详细讲解,可点击文后的相关文章链接查看,在此不再赘述。

冒泡排序法的原理

基本原理

从序列头部开始遍历,两两比较,如果前者比后者大,则交换位置,直到最后将最大的数(本次排序最大的数)交换到无序序列的尾部,从而成为有序序列的一部分;
下次遍历时,此前每次遍历后的最大数不再参与排序;
多次重复此操作,直到序列排序完成。
由于在排序的过程中总是小数往前放,大数往后放,类似于气泡逐渐向上漂浮,所以称作冒泡排序。

原理图解

Tips:蓝色代表在一轮排序中等待交换,黑色代表在该轮排序中已交换完成,红色代表已排序完成

技术图片

实现冒泡的步骤分解

使用for循环确定排序次数

由于待排序的序列只剩下一个数时已经能够确定顺序,则无需进行排序,因此,排序次数为序列长度 – 1。

技术图片

每次排序的比较次数控制

每次排序,序列中的多个数字要分别进行两两比较,多次的比较需要利用for语句来进行实现。该for循环嵌套于排序次数的for循环当中(形成双for的嵌套)。

技术图片

Tips:j 需要设置为小于 len - i - 1,减i的原因是已经排序完成的数不再参与比较,减1的原因是数组下标索引值从0开始。

核心功能 — 两两比较并根据情况交换位置

比较两数大小,如果前者比后者大,则进行数值的交换,也就是交换位置。

技术图片

冒泡排序法完整代码

技术图片

冒泡排序法的优化

假如序列的数据为:[0, 1, 2, 3, 4, 5];
使用上面的冒泡排序法进行排序,得到的结果肯定没有问题,但是,待排序的序列是有序的,理论上是无需遍历排序。
当前的算法不管初始的序列是否有序,都会进行遍历排序,效率会比较低,因此需要优化当前的排序算法。
在如下的算法中,引入一个swap变量,每一次排序之前初始化为false;若发生两数交换位置,则将其设置为true。
在每次排序结束时候判断swap是否为false,如果是,则说明序列已排序完成或者序列本身是有序序列,就不再进行下一次排序。
通过此方法,减少不必要的比较和位置交换,进一步提高算法的性能。

技术图片

冒泡排序法的效率

时间复杂度

最佳状态:待排序的序列本身是有序序列,排序次数根据优化后的代码,可以得出是n-1次,时间复杂度为O(n);
最坏的情况:待排序的序列是逆序的,此时需要排序1 + 2 +3 ……(n - 1) = n(n – 1 )/2次,
时间复杂度为O(n^2)。

空间复杂度

冒泡排序法需要一个额外空间(temp变量)来交换元素的位置,所以空间复杂度为O(1)。

算法的稳定性

当相邻元素相等时,并不需要交换位置,也就不会出现相同元素的前后顺序发生改变,所以,是稳定性排序。

O是个啥?!

时间复杂度,更准确的说该是描述一个算法在问题规模不断增大时对应的时间增长曲线。所以,这些增长数量级并不是一个准确的性能评价,可以理解为一个近似值。(空间复杂度同理)
O(n2)表示当n很大的时候,复杂度约等于Cn2,C是某个常数,简单说就是当n足够大的时候,随着n的线性增长复杂度将沿平方增长。
O(n)表示,n很大的时候复杂度约等于Cn,C是某个常数。简言之:随着n的线性增长,复杂度沿线性级别增长。
O(1)表示,n很大的时候,复杂度基本就不增长了。简言之:随着n的线性增长,复杂度不受n的影响,沿常数级别增长(此处的常数是1)。

技术图片

Tips:图中O(1)紧贴着X轴,并看不太清楚。
Tips:该图来源于“Stack Overflow”网站。

相关文章链接

算法之旅 | 选择排序法

开开心心每一天

生活艰辛,代码不易,但,不要忘记微笑!

技术图片

版权声明:该图来自“【美】莉兹·克里莫 (author)”的书籍《你今天真好看》

技术图片

技术图片

本文转载于:算法之旅 | 冒泡排序法
















以上是关于什么是冒泡法?[详细的讲下]的主要内容,如果未能解决你的问题,请参考以下文章

冒泡排序法(超详细)

C语言冒泡排序法

算法之旅 | 冒泡排序法

算法之旅 | 冒泡排序法

算法之旅 | 冒泡排序法

八大数据排序法冒泡排序法的图形理解和案例实现 | C++