什么是算法
算法的设计
如何选择算法
全排列算法
选择排序
时间复杂度

什么是算法

算法就是计算或者解决问题的步骤。
算法和程序有些类似,区别在于程序是以计算机能够理解的编程语言编写而成的,而算法是以人类能够理解的方式描述的,用于编写程序之前。

算法的设计

计算机擅长高速执行一些基本命令,但无法执行复杂的命令。此处的基本命令指的是‘做加法’或者‘在指定的内存地址上保存数据’等。
计算机就是以这些基本命令的组合为基础运行的,面对复杂的操作也是通过搭配组合这些基本命令来应对的。
如何设计算法来解决问题,也就等同于构思如何搭配组合计算机可以执行的那些基本命令来实现这些操作。

如何选择算法

一般来说,我们最为重视的是算法的运行时间,即从输入数据到输出结果这个过程所花费的时间。

举个例子

这个例子用来感受一下低效率算法的效果。
有个实验叫做猴子和打字机实验,说的是如果无数多的猴子在无数多的打字机上随机的打字,并持续无限久的时间,那么在某个时候,它们必然会打出莎士比亚的全部著作。
这里引申出一种排序算法:全排列排序。

    1、生成一个由n个数字构成的数列(不和前面生成的数列重复)
    2、如果1生成的数列按从小到大的顺序排列就将其输出,否则回到步骤1

所以,对于n个数字,最差的情况,就是直到最后才出现正确排列的情况下,我们计算一下需要多长时间。
第一个位置,我们有n种排列情况,然后确认第一个数字n;
第二个位置,我们排除了第一个位置的数字,还有n-1个数字,那就是说还有n-1种排列情况,然后确认第二个位置的数字,
第三个位置,则是n-2;
...
直到最后一个位置,此时只有一个数字,那么就是1种排列情况。
所以,总共有 n * (n-1) * (n-2) * (n-3)...3 * 2 * 1 种,也就是n!种不同的排列方法。
好的,如果 n=50

50! = 50 * 49 * 48 ...3 * 2 * 1 
    = 50 * 49 * 48... 3 * 2 
    >> 50 * 49 * 48...12 * 11 * 10 
    >> 10^40

Tips: ^ 这里代表次方.
我们大概估算一下,如果一台家用级计算机的 3.0GHz 的CPU来计算的话,它的时钟频率是3.0GHz,就是一秒钟3*10^9次,那10^ 40,大概要运算 3.3*10^30秒,1小时等于3.6*10^3秒,大约需要10^27小时,一年24*365小时,大概7*10^4,也就是说要10^22年。
即便是超级计算机,一直保持峰值360万亿次3.6*10^14来计算,也要10^17年才能算完。
天文学估算过,从大爆炸到现在,宇宙约经历了137亿年,也就是刚刚1.3*10^10年,所以要经历将近100万次大爆炸到现在这么长的时间才能得到答案。

好的,我们再来考虑一种常见的效率高一点的排序方法,选择排序。
选择排序的做法是,逐步找出最小的数字,然后将它放到已经排列好的数字的后边。
从左到右逐步确认最小的数字,第一轮需要查询n个数字,第二轮需要查询n-1个数字,以此类推,第n-1轮需要查询2个数字,第n轮需要查询1个数字。
也就是说需要 n + (n-1) + (n-2) +...+ 2 + 1 = n * (n+1) /2 步就能排序好。
同样的,如果n=50

    50 * 51 /2 = 2525;

这么看来,选择排序要比全排列排序效率要高很多。

运行时间的计算方法

我们不光要理解不同算法在运行时间上的区别,还要了解根据输入数据量的大小,算法的运行时间具体会产生多大变化。运行时间计算最直观的方法就是,实际在计算机上运行下,统计它实际花费的时间,但是就算同样的算法,在不同计算机上运行时间也会有偏差。所以我们使用“步数”来描述运行时间。而同样的在算法中,我们用时间复杂度来描述算法的运算时间,具体来说就是 忽略重要项以外的内容,全排列的时间复杂度就是O(n^2),选择排序的时间复杂度就是O(n logn), 这样就能很快的判断出谁运算更快了。