杂记【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);

猜你喜欢

转载自blog.csdn.net/CreatorGG/article/details/84871210