好玩的冒泡排序

个人笔记

  • 计算机使用的目的在于提高效率,完成人类手工几乎不会完成的大规模计算。计算机的水平的提高主要得先用起来! 第二个需要学习一些常规的算法和数据结构,否则即使达到目的,效率也是很低,不能体现计算机高效的特色。

  • 不管什么算法,都是通过某种编程语言去实现的。至于使用什么语言这要仁者见仁,智者见智了。

  • 作为非计算机专业,往往考虑的是可操作性,简洁性,一些数学软件已经实现的功能,打基础或者想了解原理去编写之外,没有必要所有都要自己去实现,舍近求远的方法往往不可取。善于借鉴前人成果,加上自己的实践体会,这才是提高编程水平的重要手段。

  • 很多教材将排序是一个编程入门的基本功。可以窥探很多编程的技巧和思想。

冒泡排序定义和算法复杂性

1.1 冒泡排序的定义

冒泡排序(英语:Bubble Sort)又称为泡式排序,是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
  这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端
  冒泡排序对 n n n个项目需要 O ( n 2 ) O({\displaystyle n^{2}}) O(n2)的比较次数,且可以原地排序。尽管这个算法是最简单了解和实现的排序算法之一,但它对于包含大量的元素的数列排序是很没有效率的。毕竟有更好的排序算法。

1.2 算法复杂性的若干分析

  冒泡排序是与插入排序拥有相等的运行时间,但是两种算法在需要的交换次数却很大地不同。在最坏的情况,冒泡排序需要 O ( n 2 ) {\displaystyle O(n^{2})} O(n2)次交换,而插入排序只要最多 O ( n ) {\displaystyle O(n)} O(n)交换。
  冒泡排序的实现(类似下面)通常会对已经排序好的数列拙劣地运行 O ( n 2 ) {\displaystyle O(n^{2})} O(n2),而插入排序在这个例子只需要 O ( n ) {\displaystyle O(n)} O(n)个运算。因此很多现代的算法教科书避免使用冒泡排序,而用插入排序取代之。冒泡排序如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,也可以把最优情况下的复杂度降低到 O ( n ) {\displaystyle O(n)} O(n)
  在这个情况,已经排序好的数列就无交换的需要。若在每次走访数列时,把走访顺序反过来,也可以稍微地改进效率。有时候称为鸡尾酒排序,因为算法会从数列的一端到另一端之间穿梭往返。

冒泡排序算法的运作如下:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较.

1.3 示例

详细步骤说明: 源自于图解LeetCode初级算法一书。 书本以队列为例。

735194

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.4 伪代码

函数 冒泡排序 输入 一个数组名称为array 其长度为length
i 从 1 到 (length - 1)
j 从 0 到 (length - 1 - i)
如果 array[j] > array[j + 1]
交换 array[j] 和 array[j + 1] 的值
如果结束
j 循环结束
i循环结束
函数结束

function bubble_sort (array, length) {
var i, j;
for(i from 0 to length-1){
for(j from 0 to length-1-i){
if (array[j] > array[j+1])
swap(array[j], array[j+1])
}
} }

1.5 C语言实现

/* Bubble sort code */
#include <stdio.h>

int main()
{
  int array[100], n, c, d, swap;

  printf("Enter number of elements\n");
  scanf("%d", &n);

  printf("Enter %d integers\n", n);

  for (c = 0; c < n; c++)
    scanf("%d", &array[c]);

  for (c = 0 ; c < n - 1; c++)
  {
    for (d = 0 ; d < n - c - 1; d++)
    {
      if (array[d] > array[d+1]) /* For decreasing order use < */
      {
        swap       = array[d];
        array[d]   = array[d+1];
        array[d+1] = swap;
      }
    }
  }

  printf("Sorted list in ascending order:\n");

  for (c = 0; c < n; c++)
     printf("%d\n", array[c]);

  return 0;
}

C编译器运行结果,输入书本的例子。
cmd

1.6 Mathematica软件实现

一行命令完成冒泡排序! Wolfram语言简洁性实用性真的不容置疑!

Notebook界面:
在这里插入图片描述
代码文本

data = {7, 3, 5, 1, 9, 4};
data //. {a___, b_, c_, d___} /; b > c -> {a, c, b, d}

我们进一步可以利用Mathematica去制作动态过程监视每一步排序过程。
在这里插入图片描述
动态演示:
在这里插入图片描述

代码文本:

data = {7, 3, 5, 1, 9, 4};
sortstep := # /. {a___, b_, c_, d___} /; b > c -> {a, c, b, d} &
sorted = Most[NestWhileList[sortstep, data, UnsameQ[##] &, 2]];
Manipulate[BarChart[sorted[[k]], PlotTheme -> "Detailed", ImageSize -> 500], {k, 2, Length[sorted], 1}]

参考资料

  1. https://mathematica.stackexchange.com/questions/152478/output-all-steps-of-sort
  2. https://www.runoob.com/w3cnote/bubble-sort.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值