js數(shù)組中的各種排序方法

冒泡排序

思路:重復遍歷數(shù)組中的元素,依次比較兩個相鄰的元素,如果前一個元素大于后一個元素,就依靠第三個變量將它們換過來,直到所有元素遍歷完。

function bubbleSort(arr){

? ? ? ? ? for(let i = 0; i < arr.length - 1; i ++){

? ? ? ? ? ? ? ? for(let j = 0; j < arr.length - 1 - i; j ++){

? ? ? ? ? ? ? ? ? ? ? if(arr[j] > arr[j+1]){? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? let tem = arr[j];

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

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

? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? }

? ? ? ? ? console.log(arr);

? ? }

? ? bubbleSort([2,5,6,1,2,9,4,6,3]);? ? // output:[1, 2, 2, 3, 4, 5, 6, 6, 9]

選擇排序

思路:每一次從數(shù)組中選出最小的一個元素,存放在數(shù)組的起始位置,然后,再從剩余未排序的數(shù)組中繼續(xù)尋找最小元素,然后放到已排序序列的末尾。直到全部數(shù)據(jù)元素排完。

function selectSort(arr){

? ? ? ? ? let min = 0; // 用來保存數(shù)組中最小的數(shù)的索引值

? ? ? ? ? for(let i = 0; i < arr.length - 1; i ++){

? ? ? ? ? ? ? ? min = i;

? ? ? ? ? ? ? ? for(let j = i + 1; j < arr.length; j ++){

? ? ? ? ? ? ? ? ? ? ? if(arr[j] < arr[min]){

? ? ? ? ? ? ? ? ? ? ? ? ? ? min = j;

? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? if(min != i){

? ? ? ? ? ? ? ? ? ? ? swap(arr,i,min);

? ? ? ? ? ? ? ? }

? ? ? ? ? }

? ? ? ? ? console.log(arr);

? ? };

? ? function swap(arr,index1,index2){?

? ? let tem = arr[index1];

? ? ? ? ? arr[index1] = arr[index2];

? ? ? ? ? arr[index2] = tem;

? ? }

? ? selectSort([7,5,1,2,6,4,8,3,2]);? ? // output: [1, 2, 2, 3, 4, 5, 6, 7, 8]

插入排序

插入算法的工作原理就是對已排序數(shù)據(jù)序列從后向前掃描,將未排序數(shù)據(jù)找到對應的位置并插入。

思路:
(1)從第一個元素開始,該元素可以被認為已經被排序了;
(2)取出下一個元素,在已經排好序的序列中從后往前掃描;
(3)直到找到小于或等于該元素的位置;
(4)將該位置后面的所有已排序的元素從后往前依次向后移一位;
(5)將該元素插入到該位置;
(6)重復步驟 2-5;

function insertSort(arr){

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

? ? ? ? ? ? ? ? let j = i,? ? ? ? ? ? key = arr[j];

? ? ? ? ? ? ? ? while( --j > -1 ){

? ? ? ? ? ? ? ? ? ? ? if(arr[j] > key){

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

? ? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

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

? ? ? ? ? }

? ? ? ? ? console.log(arr);

? ? }

? ? insertSort([12,25,41,2,3,15]); // output:[2, 3, 12, 15, 25, 41]

希爾排序

希爾排序是插入排序的一種,又稱“縮小增量排序”,是直接插入排序算法的一種更高效的改進版本。

思路:把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至 1 時,整個數(shù)據(jù)列恰好被分成一組,算法便終止。

function shellSort(arr){

? ? ? ? ? let gaps = [5, 3, 1];

? ? ? ? ? for (let g = 0; g < gaps.length; ++g) {

? ? ? ? ? ? ? ? for (let i = gaps[g]; i < arr.length; ++i) {

? ? ? ? ? ? ? ? ? ? ? let temp = arr[i];

? ? ? ? ? ? ? ? ? j = i;

? ? ? ? ? ? ? ? ? ? ? for (j; j >= gaps[g] && arr[j - gaps[g]] > temp; j -= gaps[g]) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? arr[j] = arr[j - gaps[g]];

? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? arr[j] = temp;

? ? ? ? ? ? ? ? }

? ? ? ? ? }

? ? ? ? ? console.log(arr);

? ? }

? ? shellSort([12,21,32,14,15,18]); output:[12, 14, 15, 18, 21, 32]

歸并排序

歸并排序是建立在歸并操作上的一種有效排序算法,該算法是采用分治法的一個非常典型的應用。即先進行劃分,然后再進行合并。

思路:假設對一個數(shù)組 C 進行歸并排序,步驟如下
(1)先將 C 劃分為兩個數(shù)組 A 和 B(即把數(shù)組 C 從中間分開)
(2)再分別對數(shù)組 A、B 重復步驟1的操作,逐步劃分,直到不能再劃分為止(每個子分組只剩下一個元素),至此劃分結束。
(3)然后從下層往上層不斷合并數(shù)組,每一層合并相鄰的兩個子數(shù)組。合并的過程是每次從待合并的兩個子數(shù)組中選取一個最小的元素,然后把這個元素放到合并后的數(shù)組中,不斷重復直到把兩個子數(shù)組的元素都放到合并后的數(shù)組為止。
(4)以此類推,直到合并到最上層結束,這時數(shù)據(jù)的排序已經完成。

function merge(left, right) {

? ? ? ? let result = [];

? ? ? ? while(left.length > 0 && right.length > 0) {

? ? ? ? ? ? ? if(left[0] < right[0]) {

? ? ? ? ? ? ? ? ? ? result.push(left.shift());

? ? ? ? ? ? ? }? ? ? else {

? ? ? ? ? ? ? ? ? ? ? result.push(right.shift());

? ? ? ? ? ? ? }

? ? ? ? }

? /* 當左右數(shù)組長度不等.將比較完后剩下的數(shù)組項鏈接起來即可 */

? ? ? ? return result.concat(left).concat(right);

? }

? function mergeSort(arr){

? ? ? ? if(arr.length == 1){

? ? ? ? ? ? ? return arr;

? ? ? ? };

? ? ? ? let mid = Math.floor( arr.length/2 );

? ? ? ? let left_arr = arr.slice(0, mid),

? ? ? ? ? ? ? ? right_arr = arr.slice( mid );

? ? ? ? return merge( mergeSort(left_arr), mergeSort(right_arr) );

? }

? console.log(mergeSort([12,20,30,21,15,33,26,19,40,25])); output:[12, 15, 19, 20, 21, 25, 26, 30, 33, 40]

快速排序

對冒泡排序的一種改進。通過一趟排序將要排序的數(shù)據(jù)分割成獨立的兩部分,其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都比另一部分的所有數(shù)據(jù)小,然后再按此方法對這兩部分數(shù)據(jù)分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數(shù)據(jù)變成有序序列。

思路:
(1)找基準(一般以中間項為基準)
(2)遍歷數(shù)組,小于基準的放在 left,大于基準的放在 right
(3)遞歸

function quickSort(arr){

? ? if(arr.length<=1){return arr;}? ? //如果數(shù)組<=1,則直接返回

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

? ? let pivot = arr.splice(pivotIndex,1)[0]; //找基準,并把基準從原數(shù)組刪除

? ? let left=[], right=[];? ? //定義左右數(shù)組

? ? for(let i=0; i<arr.length; i++){? ? ? ? //比基準小的放在left,比基準大的放在right

? ? ? ? if(arr[i] <= pivot){

? ? ? ? ? ? left.push(arr[i]);? ?

? ? ? ? } else {?

? ? ? ? right.push(arr[i]);

? ? ? ? }

? ? }

? ? return quickSort(left).concat([pivot],quickSort(right));? ? //遞歸

}

console.log(quickSort([5,3,4,8,6,9,12]));? // output:[3, 4, 5, 6, 8, 9, 12]

效率比較:


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 某次二面時,面試官問起Js排序問題,吾絞盡腦汁回答了幾種,深感算法有很大的問題,所以總計一下! 排序算法說明 (1...
    流浪的先知閱讀 1,252評論 0 4
  • Ba la la la ~ 讀者朋友們,你們好啊,又到了冷鋒時間,話不多說,發(fā)車! 1.冒泡排序(Bub...
    王飽飽閱讀 1,897評論 0 7
  • 今天的課程,有一個環(huán)節(jié)是兩兩一組練習“要”與“不要”,好像以前有體驗過,這是個劍拔弩張的環(huán)節(jié),兩方的情緒對抗,開始...
    當當F閱讀 265評論 0 0
  • 01 成年人的戀愛真麻煩。 晚上和朋友聊天的時候大家陷入了一場回憶殺,討論著初中高中的相識,夜晚輔導班化學老師講的...
    醬油怎么呢么黑閱讀 352評論 0 4
  • 公司的郵箱一直登錄不了,收件箱也打不開,一直報錯TypeError: $.cookie is not a func...
    十一歲的加重閱讀 1,547評論 0 0

友情鏈接更多精彩內容