JS實(shí)現(xiàn)數(shù)組排序的方法有哪些?

數(shù)組排序在日常編程中用到的其實(shí)還是比較多的大磺,比如把一組數(shù)據(jù)按時(shí)間排序,按首字母排序滩租,按大小排序等等赋秀,那么就讓我們一起來(lái)了解下常見的數(shù)組排序方法有哪些。

一說(shuō)到數(shù)組排序律想,很多人腦子里第一時(shí)間蹦出來(lái)的可能就是sort()方法沃琅。那我們就從這個(gè)原生的排序方法sort()開始講起。

語(yǔ)法:arrayObject.sort(sortby)

這里的sortby是一個(gè)參數(shù)蜘欲,規(guī)定排序的順序益眉,必須是函數(shù)。

sort()的返回值是對(duì)該數(shù)組的引用姥份,這里要注意的是郭脂,該排序方法會(huì)在原數(shù)組上直接進(jìn)行排序,并不會(huì)生成一個(gè)排好序的新數(shù)組澈歉。

還要注意的是:如果沒(méi)有使用參數(shù)sortby展鸡,那么排序的時(shí)候?qū)?huì)按字母的順序?qū)?shù)組中的元素進(jìn)行排序,說(shuō)精確點(diǎn)是按照字符編碼的順序進(jìn)行排序埃难。如果要實(shí)現(xiàn)這一點(diǎn)莹弊,首先應(yīng)該把數(shù)組的元素都轉(zhuǎn)化成字符串,以便進(jìn)行比較涡尘。

如果想按照其他標(biāo)準(zhǔn)排序忍弛,那么就要傳入?yún)?shù)sortby,即提供比較函數(shù)考抄。該函數(shù)要比較兩個(gè)值细疚,然后返回一個(gè)用于說(shuō)明這兩個(gè)值的相對(duì)順序的數(shù)字。比較參數(shù)應(yīng)該具有兩個(gè)參數(shù)a和b川梅,其返回值如下:

若a小于b疯兼,在排序后的數(shù)組中矛市,a應(yīng)該出現(xiàn)在b之前呼盆,則返回一個(gè)小于0的值

若a=b绢淀,則返回0

若a大于b出刷,則返回一個(gè)大于0的值

我們先來(lái)看兩個(gè)例子,第一個(gè)不傳入?yún)?shù)sortby姨裸,代碼如下:

var arr = ["Zhangsan", "Lisi", "Wangwu", "Hanmei", "Chendu"];

var res = arr.sort();

console.log(res);

// 打印結(jié)果為["Chendu", "Hanmei", "Lisi", "Wangwu", "Zhangsan"]

那么如果數(shù)組元素是數(shù)字呢秧倾?看如下代碼:

var arr = [524, 684, 5, 69, 15];

var res = arr.sort();

console.log(res);

// 打印結(jié)果為[15, 5, 524, 684, 69]

由上面的代碼可以看到,如果數(shù)組元素為數(shù)字的話啦扬,排序并不會(huì)按大小順序排,而是會(huì)按數(shù)字的第一個(gè)字符排序凫碌。

如果我們想要這組數(shù)字按從小到大扑毡,或者從大到小的順序排列的話,那么我們就需要傳入?yún)?shù)sortby盛险,即上文所說(shuō)的比較函數(shù)瞄摊。

function sortNum(a, b) {

return a - b;

}

var arr = [524, 684, 5, 69, 15];

var res = arr.sort(sortNum);

console.log(res);

// 打印結(jié)果為[5, 15, 69, 524, 684]

上面代碼中的sortNum就是一個(gè)比較函數(shù),我們傳入a,b兩個(gè)值苦掘,然后返回a-b的值换帜,跟據(jù)返回值進(jìn)行大小排序,如果想要從大到小排序鹤啡,只需要return b-a即可惯驼。

這里額外提一下reverse()這個(gè)方法,這個(gè)方法用于顛倒數(shù)組中元素的順序递瑰。這里要注意祟牲,只是顛倒,并不是按從大到小的順序抖部,因此我認(rèn)為它算不上是排序方法说贝。

語(yǔ)法:arrayObject.reverse()

demo代碼如下:

var arr = [524, 684, 5, 69, 15];

var res = arr.reverse();

console.log(res);

// 打印結(jié)果為[15, 69, 5, 684, 524]

除了我們常用的sort()方法,其實(shí)還有其他很多方法可以實(shí)現(xiàn)排序:

冒泡排序

快速排序

插入排序

希爾排序

選擇排序(坑未填)

歸并排序(坑未填)

堆排序(坑未填)

一慎颗、冒泡排序

冒泡排序就是遍歷數(shù)組里面的元素乡恕,一次比較兩個(gè)元素,如果它們的順序錯(cuò)誤俯萎,就把它們交換過(guò)來(lái)傲宜,直到?jīng)]有需要交換的兩個(gè)元素為止。它是一種穩(wěn)定排序算法蛋哭。

冒泡排序算法的運(yùn)作如下:(從后往前)

比較相鄰的元素躁愿。如果第一個(gè)比第二個(gè)大跷叉,就交換他們兩個(gè)。

對(duì)每一對(duì)相鄰元素作同樣的工作帖世,從開始第一對(duì)到結(jié)尾的最后一對(duì)。在這一點(diǎn)翔怎,最后的元素應(yīng)該會(huì)是最大的數(shù)。

針對(duì)所有的元素重復(fù)以上的步驟,除了最后一個(gè)。

持續(xù)每次對(duì)越來(lái)越少的元素重復(fù)上面的步驟,直到?jīng)]有任何一對(duì)數(shù)字需要比較。

——引用自百度百科《冒泡排序》

function bubbleSort(arr) {

for(var i = 0; i < arr.length; i++) {

for(var j = 0; j < arr.length; j++) {

if(arr[i] < arr[j]) {

var temp = arr[j];

arr[j] = arr[i];

arr[i] = temp;

}

}

}

return arr;

}

var arr = [524, 684, 5, 69, 15];

bubbleSort(arr);? ? // 結(jié)果為[5, 15, 69, 524, 684]

上面的代碼就是一個(gè)很好理解的冒泡排序?qū)懛ㄕ家#捎脙蓚€(gè)for循環(huán),當(dāng)i=0的時(shí)候搔啊,將arr[0]與數(shù)組里面的每一項(xiàng)比較柬祠,如果arr[0]小于某一項(xiàng),則替換它們的位置负芋,以此類推漫蛔。

二、快速排序

快速排序是對(duì)冒泡排序的一種改進(jìn)示罗。它的基本思想是:通過(guò)一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分惩猫,其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小芝硬,然后再按此方法對(duì)這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序蚜点,整個(gè)排序過(guò)程可以遞歸進(jìn)行,以此達(dá)到整個(gè)數(shù)據(jù)變成有序序列拌阴。

快速排序的過(guò)程大致分三步:

在數(shù)據(jù)集之中绍绘,選擇一個(gè)元素作為"基準(zhǔn)"(pivot)。

所有小于"基準(zhǔn)"的元素迟赃,都移到"基準(zhǔn)"的左邊陪拘;所有大于"基準(zhǔn)"的元素,都移到"基準(zhǔn)"的右邊纤壁。

對(duì)"基準(zhǔn)"左邊和右邊的兩個(gè)子集左刽,不斷重復(fù)第一步和第二步,直到所有子集只剩下一個(gè)元素為止酌媒。

——引用自阮一峰博客《快速排序的JavaScript實(shí)現(xiàn)》

封裝代碼如下:

function quickSort(arr) {

if(arr.length <= 1) {

return arr;

}

var pivotIndex = Math.floor(arr.length / 2);

var pivot = arr.splice(pivotIndex, 1)[0];

// splice()返回的是被刪除元素組成的數(shù)組

var lef = [];

var rig = [];

for(var i = 0; i < arr.length; i++) {

if(arr[i] < pivot) {

lef.push(arr[i]);

}

else {

rig.push(arr[i]);

}

}

return quickSort(lef).concat(pivot, quickSort(rig)); // 遞歸

}

var arr = [524, 684, 5, 69, 15];

quickSort(arr);? ? // 結(jié)果為[5, 15, 69, 524, 684]

三欠痴、插入排序

已知一個(gè)已有序的數(shù)據(jù)序列,需要插入一個(gè)數(shù)據(jù)秒咨,要求插入數(shù)據(jù)后這個(gè)序列依然有序喇辽,那么這個(gè)時(shí)候就需要使用插入排序。

插入排序把要排序的數(shù)組分成兩部分:第一部分包含了這個(gè)數(shù)組的所有元素雨席,但將最后一個(gè)元素除外(讓數(shù)組多一個(gè)空間才有插入的位置)菩咨,而第二部分就只包含這一個(gè)元素(即待插入元素)。在第一部分排序完成后,再將這個(gè)最后元素插入到已排好序的第一部分中抽米。

用生活中比較好理解的事物就是斗地主特占,你手里的牌已經(jīng)排好序了,摸一張新牌缨硝,要將其插入進(jìn)去摩钙,小的牌會(huì)往前插,大的牌會(huì)往后插查辩。

封裝代碼如下:

function insertSort(arr) {

for(var i = 1; i < arr.length; i++) {

if(arr[i] < arr[i - 1]) {

var temp = arr[i];

var j = i -1;

arr[i] = arr[j];

while(j >= 0 && temp < arr[j]) {

arr[j + 1] = arr[j];

j--;

}

arr[j + 1] = temp;

}

}

}

var arr = [524, 684, 5, 69, 15];

insertSort(arr);

console.log(arr);? ? // 結(jié)果為[5, 15, 69, 92, 524, 684]

如果你是需要在現(xiàn)有的已排好序的數(shù)組中插入新的元素胖笛,并且新數(shù)組也依然排好序,那么上面的代碼就需要修改一下:

function insertSort(arr, a) {

for(var i = 1; i < arr.length; i++) {

if(arr[i] >= a) {

for(var j = arr.length; j > i; j--) {

arr[j] = arr[j - 1];

}

arr[i] = a;

break;

}

}

return arr;

}

var arr = [5, 15, 69, 524, 684];

insertSort(arr, 92);? ? // 結(jié)果為[5, 15, 69, 92, 524, 684]

對(duì)于小型數(shù)組的排列宜岛,插入排序要比前兩種排序方法性能更好长踊。

四、希爾排序

希爾排序是插入排序的一種萍倡,也稱縮小增量排序身弊,是直接插入排序算法的一種更高效的改進(jìn)版本。

希爾排序是把記錄按下標(biāo)的一定增量分組列敲,對(duì)每組使用直接插入排序算法排序阱佛;隨著增量逐漸減少,每組包含的關(guān)鍵詞越來(lái)越多戴而,當(dāng)增量減至1時(shí)凑术,整個(gè)文件恰被分成一組,算法便終止所意。

——引用自百度百科《希爾排序》

封裝代碼如下:

function shellSort(arr) {

var gap = Math.ceil(arr.length / 2);

while(gap > 0) {

for(var k = 0; k < gap; k++) {

var tagArr = [];

tagArr.push(arr[k]);

for(var i = k + gap; i < arr.length; i = i + gap) {

var temp = arr[i];

tagArr.push(temp);

for(var j = i - gap; j > -1; j = j - gap) {

if(arr[j] > temp) {

arr[j + gap] = arr[j];

}

else {

break;

}

}

arr[j + gap] = temp;

}

}

gap = parseInt(gap / 2);

}

return arr;

}

var arr = [524, 684, 5, 69, 15];

shellSort(arr);? ? // 結(jié)果為[5, 15, 69, 92, 524, 684]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末淮逊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子扶踊,更是在濱河造成了極大的恐慌泄鹏,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秧耗,死亡現(xiàn)場(chǎng)離奇詭異备籽,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)分井,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門车猬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人杂抽,你說(shuō)我怎么就攤上這事诈唬。” “怎么了缩麸?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵铸磅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)阅仔,這世上最難降的妖魔是什么吹散? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮八酒,結(jié)果婚禮上空民,老公的妹妹穿的比我還像新娘。我一直安慰自己羞迷,他們只是感情好界轩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著衔瓮,像睡著了一般浊猾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上热鞍,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天葫慎,我揣著相機(jī)與錄音,去河邊找鬼薇宠。 笑死偷办,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的澄港。 我是一名探鬼主播椒涯,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼慢睡!你這毒婦竟也來(lái)了逐工?” 一聲冷哼從身側(cè)響起铡溪,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤漂辐,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后棕硫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體髓涯,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年哈扮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纬纪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡滑肉,死狀恐怖包各,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情靶庙,我是刑警寧澤问畅,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響护姆,放射性物質(zhì)發(fā)生泄漏矾端。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一卵皂、第九天 我趴在偏房一處隱蔽的房頂上張望秩铆。 院中可真熱鬧,春花似錦灯变、人聲如沸殴玛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)族阅。三九已至,卻和暖如春膝捞,著一層夾襖步出監(jiān)牢的瞬間坦刀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工蔬咬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鲤遥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓林艘,卻偏偏與公主長(zhǎng)得像盖奈,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狐援,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 數(shù)組排序在日常編程中用到的其實(shí)還是比較多的啥酱,比如把一組數(shù)據(jù)按時(shí)間排序爹凹,按首字母排序,按大小排序等等镶殷,那么就讓我們一...
    一木_qintb閱讀 13,000評(píng)論 1 2
  • 某次二面時(shí)禾酱,面試官問(wèn)起Js排序問(wèn)題,吾絞盡腦汁回答了幾種绘趋,深感算法有很大的問(wèn)題颤陶,所以總計(jì)一下! 排序算法說(shuō)明 (1...
    流浪的先知閱讀 1,193評(píng)論 0 4
  • Ba la la la ~ 讀者朋友們陷遮,你們好啊滓走,又到了冷鋒時(shí)間,話不多說(shuō)帽馋,發(fā)車搅方! 1.冒泡排序(Bub...
    王飽飽閱讀 1,797評(píng)論 0 7
  • 2015-16賽季注定令人銘記許久腰懂。首先是勇士的73勝梗逮,打破塵封20年的常規(guī)賽記錄。季后賽西部風(fēng)起云涌绣溜,每一輪都是...
    鰱魚頭_小皮閱讀 514評(píng)論 0 2
  • 在這男女平等的社會(huì)里怖喻,其實(shí)我個(gè)人覺(jué)得還是有很多的“不平等”底哗。不然怎么會(huì)有“上的廳堂,下得廚房”一說(shuō)锚沸?有人說(shuō)再...
    流年_9df3閱讀 259評(píng)論 2 0