排序算法的原理无需多说,直接上代码
1 -module(quicksort). 2 -export([start/1]). 3 4 %% 程序入口 5 %% List:用户输入的待排序的数值列表 6 start(List) -> 7 SortedList = calu(List), 8 io:format("sorted list:~w~n", [SortedList]). 9 10 %% 得到排序后的数值列表 11 calu([Key|RestList]) -> 12 {LittleList, GreatList} = calu_sort(Key, RestList, [], []), 13 calu(LittleList) ++ [Key] ++ calu(GreatList); 14 calu([]) -> 15 []. 16 17 %% 快速排序算法 18 %% Key:列表中的第一个元素 19 %% [Element|RestElements]:列表中的其它元素 20 %% LittleList:小于等于Key的数值组成的列表 21 %% GreatList:大于Key的数值组成的列表 22 calu_sort(Key, [Element|RestElements], LittleList, GreatList) -> 23 if 24 Element =< Key -> 25 calu_sort(Key, RestElements, [Element] ++ LittleList, GreatList); 26 Element > Key -> 27 calu_sort(Key, RestElements, LittleList, [Element] ++ GreatList) 28 end; 29 calu_sort(_Key, [], LittleList, GreatList) -> 30 {LittleList, GreatList}.
注意事项:代码第一次运行的时候,结果怎么都不对,调试之后发现问题出在24行的Element =< Key(变量)表达式,写成了Element =< key(原子),由于Element是数值,key是原子,根据Erlang的排序规则,数值小于原子,所以结果不正确。由于变量名必须以大写开始,需要按住shirt键输入,有时候不注意没按住shirt就变成了原子。
这种问题在其它编程语言中是很难出现的,对于静态类型语言,直接就给出未定义符号的编译错误,对于动态语言,不同类型的数据一般是不予比较的。所以在Erlang编程中要万分小心,不要把变量名写成原子,否则会出现编译通过而运行时出现各种异常结果的情况。
利用list comprehension语法,可以写出更简单的代码,如下所示
1 -module(quicksort). 2 -export([qsort/1]). 3 4 qsort([]) -> []; 5 qsort([Pivot|T]) -> 6 qsort([X||X <- T,X < Pivot]) 7 ++[Pivot]++ 8 qsort([X||X <- T,X >= Pivot]).