排序算法
排序也是在程序中經(jīng)常用到的算法。無論使用冒泡排序還是快速排序旧烧,排序的核心是比較兩個(gè)元素的大小影钉。如果是數(shù)字,我們可以直接比較掘剪,但如果是字符串或者兩個(gè)對(duì)象呢平委?直接比較數(shù)學(xué)上的大小是沒有意義的,因此夺谁,比較的過程必須通過函數(shù)抽象出來廉赔。
通常規(guī)定:
對(duì)于兩個(gè)元素x和y肉微,如果認(rèn)為x < y,則返回-1;
如果認(rèn)為x == y蜡塌,則返回0;
如果認(rèn)為x > y碉纳,則返回1;
這樣,排序算法就不用關(guān)心具體的比較過程馏艾,而是根據(jù)比較結(jié)果直接排序劳曹。
JavaScript的Array的sort()方法就是用于排序的,但是排序結(jié)果可能讓你大吃一驚:
/ 看上去正常的結(jié)果:
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];
// apple排在了最后:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft", 'apple']
// 無法理解的結(jié)果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]
第二個(gè)排序把a(bǔ)pple排在了最后琅摩,是因?yàn)樽址鶕?jù)ASCII碼進(jìn)行排序铁孵,而小寫字母a的ASCII碼在大寫字母之后。
第三個(gè)排序結(jié)果是什么鬼迫吐?簡(jiǎn)單的數(shù)字排序都能錯(cuò)库菲?
這是★★★因?yàn)锳rray的sort()方法默認(rèn)把所有元素先轉(zhuǎn)換為String再排序账忘,結(jié)果'10'排在了'2'的前面志膀,因?yàn)樽址?1'比字符'2'的ASCII碼小。
如果不知道sort()方法的默認(rèn)排序規(guī)則鳖擒,直接對(duì)數(shù)字排序溉浙,絕對(duì)栽進(jìn)坑里!
幸運(yùn)的是蒋荚,sort()方法也是一個(gè)高階函數(shù)戳稽,它還可以接收一個(gè)比較函數(shù)來實(shí)現(xiàn)自定義的排序。
★要按數(shù)字大小排序期升,我們可以這么寫:
var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
if (x < y) {
return -1;
}
if (x > y) {
return 1;
}
return 0;
}); // [1, 2, 10, 20]
如果★要倒序排序惊奇,我們可以把大的數(shù)放前面:
var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
if (x < y) {
return 1;
}
if (x > y) {
return -1;
}
return 0;
}); // [20, 10, 2, 1]
★默認(rèn)情況下,Array的sort()方法是對(duì)字符串排序播赁,是按照ASCII的大小比較的.
現(xiàn)在颂郎,我們提出排序應(yīng)該忽略大小寫,★按照字母序排序容为。要實(shí)現(xiàn)這個(gè)算法乓序,不必對(duì)現(xiàn)有代碼大加改動(dòng),只要我們能定義出忽略大小寫的比較算法就可以:
var arr = ['Google', 'apple', 'Microsoft'];
arr.sort(function (s1, s2) {
x1 = s1.toUpperCase();
x2 = s2.toUpperCase();
if (x1 < x2) {
return -1;
}
if (x1 > x2) {
return 1;
}
return 0;
}); // ['apple', 'Google', 'Microsoft']
★忽略大小寫來比較兩個(gè)字符串坎背,實(shí)際上就是先把字符串都變成大寫(或者都變成小寫)替劈,再比較。
從上述例子可以看出得滤,高階函數(shù)的抽象能力是非常強(qiáng)大的陨献,而且,核心代碼可以保持得非常簡(jiǎn)潔懂更。
最后友情提示湿故,sort()方法會(huì)直接對(duì)Array進(jìn)行修改阿趁,它返回的結(jié)果仍是當(dāng)前Array:
var a1 = ['B', 'A', 'C'];
var a2 = a1.sort();
a1; // ['A', 'B', 'C']
a2; // ['A', 'B', 'C']
a1 === a2; // true, a1和a2是同一對(duì)象
【補(bǔ)充解釋】:
http://www.imooc.com/wenda/detail/330819?t=199418