个人笔记
计算机使用的目的在于提高效率,完成人类手工几乎不会完成的大规模计算。计算机的水平的提高主要得先用起来! 第二个需要学习一些常规的算法和数据结构,否则即使达到目的,效率也是很低,不能体现计算机高效的特色。
不管什么算法,都是通过某种编程语言去实现的。至于使用什么语言这要仁者见仁,智者见智了。
作为非计算机专业,往往考虑的是可操作性,简洁性,一些数学软件已经实现的功能,打基础或者想了解原理去编写之外,没有必要所有都要自己去实现,舍近求远的方法往往不可取。善于借鉴前人成果,加上自己的实践体会,这才是提高编程水平的重要手段。
很多教材将排序是一个编程入门的基本功。可以窥探很多编程的技巧和思想。
冒泡排序定义和算法复杂性
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.3 示例
详细步骤说明: 源自于图解LeetCode初级算法一书。 书本以队列为例。
7 | 3 | 5 | 1 | 9 | 4 |
---|
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编译器运行结果,输入书本的例子。
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}]
参考资料