Saturday, February 27, 2010

排序:插入排序和归并排序比较

排序算法的可以用两种不同的标准分类:
1. 存储空间
2. 稳定(stable)

所谓存储空间指的是算法需要的外部空间是不是一个常数。当需要的外部存储空间是常数时,这个排序就是原地排序(in place sort)。反之就不是。计算机科学就是一个时间和空间的妥协,可以用空间换时间,也可以用时间换空间。 所谓稳定,就是相等元素的相对位置不变。例子: 1,3,1,6中两个1的相对位置必须保持一致。

插入排序(Insertion Sort)是算法导论(Introduction to Algorithm)介绍的第一个排序算法,它的优点是算法简洁,实现(implementation)方便,稳定(相同元素的相对位置保持不变),而且是原地排序。缺点是时间复杂度为n2,也就是慢。
归并排序(Merge Sort)则是介绍的第二个算法,优点是快,时间复杂度是nlg(n),并且稳定。缺点是递归,比插入排序复杂,不是原地排序。

插入排序的算法表述:
把n维数组分成前后两个部分,视前半部分为已排序的(sorted),后半部分为未排序的(unsorted)。
每次循环取出未排序部分(unsorted)的第一个元素,逐个比较它和已排序部分(sorted)的大小,并且插入到已排序部分(sorted)。

归并排序是一种“分治”(Divide and conquer)算法:把问题(problem)分成若干的小的问题逐个解决。
“分治”算法的三个步骤:
1. 分解(devide): 将原问题分解为一系列子问题。
2. 解决(conquer): 递归地解答各个子问题,若子问题够小,可直接求解。
3. 合并(combine): 将子问题的结果合并成原问题的解。
对于归并排序来说就是:
1. 将n个元素分解为n/2个子序列。
2. 再用归并算法递归解决这两个字序列的问题。
3. 合并两个已排完序的序列。
抽象的数学证明很难给人一个具象的感受,所以需要实验来感受一下。
实验环境:
CPU: Intel Core2 Duo T6400 @ 2.0GHZ
语言: C#(.NET 3.5 SP1) / C++(gcc 3.4.5)

实验数据:
0至100000之间的90000个随机数。

MergeSort(C#):

Insertion Sort(C#):

C#结果:
归并排序(merge sort): 00:00:00.0960054
插入排序(insertion sort): 00:00:49.5428337

Merge Sort(C++):

Insertion Sort(C++):

C++结果(毫秒):
归并排序(merge sort): 78
插入排序(insertion sort): 5273

从实验结果来说,当数据量很大的时候,归并排序的性能(performance)远好于插入排序。
实验同时也表明对于一个好的算法其性能表现比较一致,C#和C++在归并排序的测评上表现相近。但是对一个相对较差的算法来说,更高级的语言似乎会放大这个差距,C++和C#相差10倍。

总结:
归并排序是用空间换时间,而插入排序是用时间换空间。

Saturday, February 6, 2010

我的坐标

这个测试结果如下:
政治立场坐标 0.8 文化立场坐标 0.8 经济立场坐标 0.4 结果说明: 政治观念坐标,负值为左,即威权主义 (Authoritarianism),正值为右,即自由主义 (Libertarianism)。 社会文化观念坐标,负值为保守与复古派 (Conservatism),正值为自由与激进派 (Liberalism)。 经济观念坐标,负值为左,即集体主义与福利主义 (Welfarism, Collectivism),正值为右,即新自由主义(Neoliberalism)。 三个维度的最大区间均为 [-2,2]。
测试表明我是提倡自由主义和激进的右派(Rightist)。