Chapter 1
本章结构
1.1Java语法
1.2数据抽象
1.3集合类抽象数据类型:背包 (Bags) 、队列 (Queues) 、栈 (Stacks)
1.4算法分析
1.5连通性问题-Case Study: Union - Find ADT
本节开篇使用了一个ThreeSum程序进行示例:
ThreeSum所起到的作用为Count the number of triples in a file of N integers that sum to 0,简单来说,就是从N个数里面取3个数的组合,统计这些组合和为零的数量。
public class ThreeSum {public static int count(int[] a){int N = a.length;int cnt = 0;for (int i = 0; i < N; i++)for (int j = i+1; j < N; j++)for (int k = j+1; k < N; k++)if (a[i]+a[j]+a[k] == 0)cnt++;return cnt;}public static void main(String[] args){int[] a = In.readInts(args[0]);StdOut.println(count(a));} }
与此同时,我们需要一个计时器来确定程序运行的时间,书上给出了一种计时器的实现方案,大概就是先在算法程序开始运行前先记录当前的系统时间,当算法运算完毕后,再次记录当前的系统时间,然后对两个时间进行时间差的运算便可得到整个算法所消耗的时间。
public class StopWatch {private final long start;public StopWatch(){ start = System.currentTimeMillis(); }public double elapseTime(){ long now = System.currentTimeMillis();return (now - start) / 1000.0;}public static void main(String[] args){int N = Integer.parseInt(args[0]);int[] a = new int[N];for (int i = 0; i < N; i++)a[i] = StdRandom.uniform(-1000000, 1000000);StopWatch timer = new StopWatch();int cnt = ThreeSum.count(a);double time = timer.elapseTime();StdOut.println(cnt + " triples " + time + " seconds ");} }
D.E Knuth认为,一个程序运行的总时间主要和两点有关:
a.执行每条语句的耗时;
b.执行每条语句的频率;
如在Threesum.count()中的if语句会执行N(N-1)(N-2)/6次(由排练组合N个选3个可得)
正是这些执行最频繁的指令决定了程序运行的总时间,而这些指令也被称为程序的内循环inner loop。许多程序的运行时间往往取决于这一小部分指令的耗时。
ThreeSum运行时间分析
语句块 | 运行时间 | 频率 | 总时间 |
cnt++ | t0 | 取决于输入x | t0*x |
for对k的循环 | t1 | N取3的组合数 | t1*C N 3 |
for对j的循环 | t2 | N取2的组合数 | t2*C N 2 |
for对i的循环 | t3 | N | t3*N |
count方法 | t4 | 1 | t4 |
总时间 | 上述汇总求和 | ||
近似 | ~(t1/6)N^3 | ||
增长的数量级 | N^3 |
至于如何对一些数学模型进行总时间的计算,作者也给了微积分方面的相应解决方案,个人觉得比用数列求和的方式做高级点。
事实上,为任何程序建立数学模型从理论上来说都是可行的,只不过有时候处理过程和方法会变得很复杂。
-----------------------------------------------------------------------------------------------------------------------
小结:
对于大多数程序,得到其运行时间的数学模型的步骤如下:
1.确定输入模型input model,定义问题的规模。如在ThreeSum中,输入规模即是标准输入中大小为N的整型数组a[N]。
2.识别内循环inner loop。对应回ThreeSum的例子,内循环便是三层的for循环。
3.根据内循环中的操作确定成本模型。所谓成本模型,即是算法中的基本操作。如ThreeSum的成本模型则是对数组元素的访问次数。
4.对于给定的输入,判断这些操作的执行效率。