1. 程式人生 > >雜記【2】常見排序演算法-JavaScript

雜記【2】常見排序演算法-JavaScript

文章目錄

直接插入排序法

// 直接插入排序法
function InsertSort(array){
    var len = array.length;
    array.unshift(0); //左側哨兵,防止越界

    for(var i=2; i<len+1; i++){
        array[0] = array[i];
        var j;
        for
(j=i; array[j-1]>array[0]; j--){ array[j] = array[j-1]; } array[j] = array[0]; } array.shift(); //除掉臨時變數 } var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57]; InsertSort(a); console.log(a);

希爾排序法

希爾排序法是對直接插入排序法的優化

function ShellSort(array){
    var len =
array.length; var d = Math.floor(len/2); //獲取分組間距 array.unshift(0); //在陣列開頭補多一個臨時變數 while(d>0){ for(var i=d+1; i<len+1; i++ ){ array[0] = array[i]; var j; for(j=i; j>0 && array[j-d]>array[0]; j-=d){ array[j] = array[
j-d]; } array[j] = array[0]; } d = Math.floor(d/2); } array.shift(); //去除臨時變數 } var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57]; ShellSort(a); console.log(a);

氣泡排序法

最簡單的排序法

function bubbleSort(array){

    var len = array.length;
    var temp = 0;

    for(var i=len-1; i>0; i--){
        for(var j=0; j<i; j++){
            if(array[j] > array[j+1]){
                temp = array[j];
                array[j] = array[j+1];
                array[j+1] = temp;
            }
        }
    }
}

var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
bubbleSort(a);
console.log(a);

快速排序法

快速排序法相當於對氣泡排序的改進

//掃描函式
function partition(array, first, end){
    
    var pivot = 0, temp = 0;
    var p = first, q = end;
    
    while(p<q){
        while(p<q && array[p]<=array[q]) q--; //從右向左掃描
        if(p<q){
            temp = array[p];
            array[p] = array[q];
            array[q] = temp;
        }
        
        while(p<q && array[p]<=array[q]) p++; //從左向右掃描
        if(p<q){
            temp = array[p];
            array[p] = array[q];
            array[q] = temp;
        }
    }
    
    pivot = p;
    return pivot;
}

//快排函式
function QuickSort(array, first, end){
    if(first>=end) return;
    else{
        //進行一輪掃描,返回一箇中間值,將比中間值小的數放在中間值左側,比中間值大的數放在中間值右側
        var pivot = partition(array, first, end); 
        QuickSort(array, first, pivot-1); //對左側無序區進行快排
        QuickSort(array, pivot+1, end); //對右側無序區進行快排
    }
}

var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
QuickSort(a, 0, a.length-1);
console.log(a);


選擇排序法

從無序區間選擇最小/最大值放到有序區間

function selectSort(array){
    var len = array.length;

    for(var i=0; i<len; i++){
        
        var min = i;

        for(var j=i+1; j<len; j++){
            if(array[j]<array[min]){
                min = j;
            }
        }

        if(array[i] != array[min]){
            var temp = array[i];
            array[i] = array[min];
            array[min] = temp;
        }
    }
}

var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
selectSort(a);
console.log(a);


堆排序

選擇排序的優化版,先建堆(大根堆/小根堆),再抽出根結點放入有序區間,然後調整堆

//堆調整函式,此處使用大根堆
function sift(array, iFrom, iTo){
    var i,j,temp;
    i = iFrom; j = 2*i;
    
    while(j <= iTo){
        if(j < iTo && array[j] < array[j+1]) j++; //比較左右孩子,讓j指向較大者
        if(array[i] > array[j]) break; //根節點比左右子結點都大時,無需調整
        else{
            //將根節點和較大的子節點交換
            temp = array[i]; 
            array[i] = array[j];
            array[j] = temp;
            
            //進入下一層調整
            i = j; j = j * 2;
        }
    }
}

function HeapSort(array){
    var len = array.length;
    var temp = 0;
    var i = Math.floor(len/2);

    array.unshift(0);

    //初始建堆
    for(; i >= 1; i--){
        sift(array, i, len);
    }

    for(i=1; i<len; i++){
        temp = array[1]; array[1]=array[len-i+1]; array[len-i+1]=temp;
        sift(array, 1, len-i);
    }

    array.shift();
}

var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
HeapSort(a);
console.log(a);


二路歸併排序(遞迴版)

//合併兩個相鄰有序的子序列,即 array[iFrom]~array[iMiddle] 與 array[iMiddle+1]~array[iTo]
function Merge(array, iFrom, iMiddle, iTo){
    var assist = new Array(array.length); //合併時用的輔助儲存空間
    var i = iFrom; var j = iMiddle + 1; var k = iFrom;

    while(i <= iMiddle && j <= iTo){
        if(array[i] < array[j]) assist[k++] = array[i++]; //取array[i]和array[j]中較小者存入assist[k]
        else assist[k++] = array[j++];
    }

    while(i <= iMiddle )
        assist[k++] = array[i++];
    
    while(j <= iTo )
        assist[k++] = array[j++];

    for(i = iFrom; i<= iTo; i++){
        array[i] = assist[i];
    }
}

//iFrom和iTo指定了排序區間
function MergeSort1(array, iFrom, iTo){
    if(iFrom == iTo) return;
    var iMiddle = Math.floor((iFrom+iTo)/2);
    MergeSort1(array, iFrom, iMiddle);
    MergeSort1(array, iMiddle+1, iTo);
    Merge(array, iFrom, iMiddle, iTo);
}

var a = [256,13,42,7,1,99,130,22,314,25,2,87,64,12,57];
MergeSort1(a, 0, a.length-1);
console.log(a);