JavaScript實現(xiàn)in-place思想的快速排序方法
快速排序,又稱劃分交換排序。以分治法為策略實現(xiàn)的快速排序算法。
本文主要要談的是利用javascript實現(xiàn)in-place思想的快速排序
分治法:
在計算機科學(xué)中,分治法是建基于多項分支遞歸的一種很重要的算法范式。字面上的解釋是“分而治之”,就是把一個復(fù)雜的問題分成兩個或更多的相同或相似的子問題,直到最后子問題可以簡單的直接求解,原問題的解即子問題的解的合并。(摘自維基百科)
快速排序的思想
數(shù)組中指定一個元素作為標(biāo)尺,比它大的放到該元素后面,比它小的放到該元素前面,如此重復(fù)直至全部正序排列。
快速排序分三步:
選基準(zhǔn):在數(shù)據(jù)結(jié)構(gòu)中選擇一個元素作為基準(zhǔn)(pivot)
劃分區(qū):參照基準(zhǔn)元素值的大小,劃分無序區(qū),所有小于基準(zhǔn)元素的數(shù)據(jù)放入一個區(qū)間,所有大于基準(zhǔn)元素的數(shù)據(jù)放入另一區(qū)間,分區(qū)操作結(jié)束后,基準(zhǔn)元素所處的位置就是最終排序后它應(yīng)該所處的位置
遞歸:對初次劃分出來的兩個無序區(qū)間,遞歸調(diào)用第 1步和第 2步的算法,直到所有無序區(qū)間都只剩下一個元素為止。
現(xiàn)在先說說普遍的實現(xiàn)方法(沒有用到原地算法)
function quickSort(arr) {
if (arr.length <= 1) return ;
//取數(shù)組最接近中間的數(shù)位基準(zhǔn),奇數(shù)與偶數(shù)取值不同,但不印象,當(dāng)然,你可以選取第一個,或者最后一個數(shù)為基準(zhǔn),這里不作過多描述
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex, 1)[0];
//左右區(qū)間,用于存放排序后的數(shù)
var left = [];
var right = [];
console.log('基準(zhǔn)為:' + pivot + ' 時');
for (var i = 0; i < arr.length; i++) {
console.log('分區(qū)操作的第 ' + (i + 1) + ' 次循環(huán):');
//小于基準(zhǔn),放于左區(qū)間,大于基準(zhǔn),放于右區(qū)間
if (arr[i] < pivot) {
left.push(arr[i]);
console.log('左邊:' + (arr[i]))
} else {
right.push(arr[i]);
console.log('右邊:' + (arr[i]))
}
}
//這里使用concat操作符,將左區(qū)間,基準(zhǔn),右區(qū)間拼接為一個新數(shù)組
//然后遞歸1,2步驟,直至所有無序區(qū)間都 只剩下一個元素 ,遞歸結(jié)束
return quickSort(left).concat([pivot], quickSort(right));
}
var arr = [14, 3, 15, 7, 2, 76, 11];
console.log(quickSort(arr));
/*
* 基準(zhǔn)為7時,第一次分區(qū)得到左右兩個子集[ 3, 2,] 7 [14, 15, 76, 11];
* 以基準(zhǔn)為2,對左邊的子集[3,2]進行劃分區(qū)排序,得到[2] 3。左子集排序全部結(jié)束
* 以基準(zhǔn)為76,對右邊的子集進行劃分區(qū)排序,得到[14, 15, 11] 76
* 此時對上面的[14, 15, 11]以基準(zhǔn)為15再進行劃分區(qū)排序, [14, 11] 15
* 此時對上面的[14, 11]以基準(zhǔn)為11再進行劃分區(qū)排序, 11 [14]
* 所有無序區(qū)間都只剩下一個元素,遞歸結(jié)束
*
*/
通過斷點調(diào)試,可得出結(jié)果。
弊端:
它需要Ω(n)的額外存儲空間,跟歸并排序一樣不好。在生產(chǎn)環(huán)境中,需要額外的內(nèi)存空間,影響性能。
同時,很多人認(rèn)為上邊的就是真正的快速排序了。 所以,在下面,很有必要的推薦in-place算法的快速排序
有關(guān)于原地算法可參考維基百科,被墻的同學(xué),百度也差不多。
in-place
快速排序一般是用遞歸實現(xiàn),最關(guān)鍵是partition分割函數(shù),它將數(shù)組劃分為兩部分,一部分小于pivot,另一部分大于pivot。具體原理上邊提過
function quickSort(arr) {
// 交換
function swap(arr, a, b) {
var temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
// 分區(qū)
function partition(arr, left, right) {
/**
* 開始時不知最終pivot的存放位置,可以先將pivot交換到后面去
* 這里直接定義最右邊的元素為基準(zhǔn)
*/
var pivot = arr[right];
/**
* 存放小于pivot的元素時,是緊挨著上一元素的,否則空隙里存放的可能是大于pivot的元素,
* 故聲明一個storeIndex變量,并初始化為left來依次緊挨著存放小于pivot的元素。
*/
var storeIndex = left;
for (var i = left; i < right; i++) {
if (arr[i] < pivot) {
/**
* 遍歷數(shù)組,找到小于的pivot的元素,(大于pivot的元素會跳過)
* 將循環(huán)i次時得到的元素,通過swap交換放到storeIndex處,
* 并對storeIndex遞增1,表示下一個可能要交換的位置
*/
swap(arr, storeIndex, i);
storeIndex++;
}
}
// 最后: 將pivot交換到storeIndex處,基準(zhǔn)元素放置到最終正確位置上
swap(arr, right, storeIndex);
return storeIndex;
}
function sort(arr, left, right) {
if (left > right) return;
var storeIndex = partition(arr, left, right);
sort(arr, left, storeIndex - 1);
sort(arr, storeIndex + 1, right);
}
sort(arr, 0, arr.length - 1);
return arr;
}
console.log(quickSort([8, 4, 90, 8, 34, 67, 1, 26, 17]));
分區(qū)的優(yōu)化
這里細(xì)心的同學(xué)可能會提出,選取不同的基準(zhǔn)時,是否會有不同性能表現(xiàn),答案是肯定的,但,因為,我是搞前端的,對算法不是很了解,所以,這個坑留給厲害的人來填補。
復(fù)雜度
快速排序是排序速度最快的算法,它的時間復(fù)雜度是O(log n)
在平均狀況下,排序n個項目要Ο(n log n)次比較。在最壞狀況下則需要Ο(n2)次比較.
以上所述是小編給大家介紹的JavaScript實現(xiàn)in-place思想的快速排序方法,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復(fù)大家的,在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
JS實現(xiàn)模擬百度搜索“2012世界末日”網(wǎng)頁地震撕裂效果代碼
這篇文章主要介紹了JS實現(xiàn)模擬百度搜索“2012世界末日”網(wǎng)頁地震撕裂效果代碼,引入第三方插件實現(xiàn)頁面的抖動、撕裂及圖片等效果,需要的朋友可以參考下2015-10-10
JS實現(xiàn)瀏覽器點擊下載圖片功能案例分析【親測有效】
這篇文章主要介紹了JS實現(xiàn)瀏覽器點擊下載圖片功能,對比分析了同源與不同源兩種解決方案,并以實際案例形式分析了不同源情況下針對文件點擊下載的具體實現(xiàn)技巧與相關(guān)注意事項,需要的朋友可以參考下2023-04-04
比JSON.stringify快兩倍的fast-json-stringify性能對比分析
這篇文章主要為大家介紹了比JSON.stringify快兩倍的fast-json-stringify性能對比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
QTreeWidget中MainWindow窗體中布局器不起作用詳解
本文主要介紹了QTreeWidget中MainWindow窗體中布局器不起作用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
JavaScript 異步調(diào)用框架 (Part 1 - 問題 & 場景)
在Ajax應(yīng)用中,調(diào)用XMLHttpRequest是很常見的情況。特別是以客戶端為中心的Ajax應(yīng)用,各種需要從服務(wù)器端獲取數(shù)據(jù)的操作都通過XHR異步調(diào)用完成。2009-08-08
JS實現(xiàn)仿雅虎首頁快捷登錄入口及導(dǎo)航模塊效果
這篇文章主要介紹了JS實現(xiàn)仿雅虎首頁快捷登錄入口及導(dǎo)航模塊效果,涉及JavaScript響應(yīng)鼠標(biāo)事件遍歷頁面元素的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-09-09

