js实现常见排序方法

// 交换函数
function swap(arr,i,j) {
    var temp=arr[i];
    arr[i]=arr[j];
    arr[j]=temp;
}

// 冒泡排序
function bubleSort(arr) {
    var flag=true;
    for(var i=0,len=arr.length;i<len&&flag;i++){
        flag=false;
        for(var j=len-1;j>i;j--){
            if(arr[j]<arr[j-1]){
                swap(arr,j,j-1);
                flag=true;
            }
        }
    }
    return arr;
}

console.log('冒泡排序:',bubleSort([8,3,5,1,5,2,1]));
console.log('冒泡排序:',bubleSort([]));

// 选择排序

function selectSort(arr) {

    for(var i=0,len=arr.length;i<len-1;i++){
        var index=i;
        for(var j=i+1;j<len;j++){
            if(arr[j]<arr[index]){
                index=j;
            }
        }
        if(i!==index){
            swap(arr,i,index);
        }

    }
    return arr;
}
console.log('选择排序:',selectSort([8,3,5,1,5,2,1]));

// 直接插入排序
function insertSort(arr) {
    for(var i=1,len=arr.length;i<len;i++){
        var temp;
        if(arr[i]<arr[i-1]){
            temp=arr[i];
            for(var j=i-1;arr[j]>temp;j--){
                arr[j+1]=arr[j];
            }
            arr[j+1]=temp;
        }

    }
    return arr;
}
console.log('直接插入排序:',insertSort([8,3,5,1,5,2,1]));

//希尔排序
function shellSort(arr){
    var increment=arr.length;
    do{
        increment=Math.floor(increment/3)+1; // 注意js中的取整运算
        for(var i=increment,len=arr.length;i<len;i++){
            if(arr[i]<arr[i-increment]){
                var temp=arr[i];
                for(var j=i-increment;j>=0&&temp<arr[j];j-=increment){
                    arr[j+increment]=arr[j];
                }
                arr[j+increment]=temp;
            }
        }
    }while(increment>1);
    return arr;
}
console.log('希尔排序:',shellSort([8,3,5,1,5,2,1]));

//堆排序
function heapSort(arr) {
    for(var i=Math.floor(arr.length/2)-1;i>=0;i--){ // 构建大顶堆
        heapAdjust(arr,i,arr.length-1);
    }

    for(var j=arr.length-1;j>=0;j--){
        //将堆顶元素与最后一个元素交换
        var temp=arr[0];
        arr[0]=arr[j];
        arr[j]=temp;
        //调整前j-1个元素组成的堆
        heapAdjust(arr,0,j-1);
    }
    return arr;
}

function heapAdjust(arr,s,m) { // s是要调整元素的下标,m是堆中最后一个元素的下标
    var temp,j;
    temp=arr[s];
    for(j=2*s+1;j<=m;j=2*j+1){
        if(j<m&&arr[j]<arr[j+1])
            j++;
        if(temp>=arr[j]) // 如果arr[s]比其左右子节点都大,则跳出循环,此结点调整完毕
            break;
        arr[s]=arr[j]; // 否则当前结点的值被较大子节点代替
        s=j;    // 并将当前结点(接下来要调整的结点)设为较大子节点
    }
    arr[s]=temp;
}
console.log('堆排序:',heapSort([8,3,5,1,5,2,1]));
console.log('堆排序:',heapSort([1,2]));

//归并排序
function mergeSort(arr) {
    if(arr.length===0){return [];}
    Msort(arr,arr,0,arr.length-1);
    return arr;
}

function Msort(arr,res,s,t) {
    var m;
    var TR2=[];
    if(s===t){
        res[s]=arr[s];
    }else{
        m=Math.floor((s+t)/2);
        Msort(arr,TR2,s,m);
        Msort(arr,TR2,m+1,t);
        Merge(TR2,res,s,m,t);
    }
}
// 将有序的SL[i...m]和SL[m+1...n]合并为有序的res[i...n]
function Merge(SL,res,i,m,n) {
    var j,k,p;
    for(k=i,j=m+1;i<=m&&j<=n;k++){ //从头开始遍历两个有序数组,直到有一个遍历到最后
        if(SL[i]<SL[j]) { // 较小的放在前面
            res[k]=SL[i++];
        }else{
            res[k]=SL[j++];
        }
    }
    if(i<=m){
        for(p=0;p<=m-i;p++){res[k+p]=SL[i+p];}
    }
    if(j<=n){
        for(p=0;p<=n-j;p++){res[k+p]=SL[j+p];}
    }

}
console.log('归并排序:',mergeSort([8,3,5,1,5,2,1]));
console.log('归并排序:',mergeSort([]));

// 快速排序
function QuikSort(arr) {
    Qsort(arr,0,arr.length-1);
    return arr;
}

function Qsort(arr,low,high) {
    var pivot;
    if(low<high){
        pivot=Partition(arr,low,high);

        Qsort(arr,low,pivot-1);
        Qsort(arr,pivot+1,high);
    }
}
function Partition(arr,low,high) {
    // 三数取中,作为枢轴
    var m=low+Math.floor((high-low)/2);
    if(arr[low]>arr[high])
        swap(arr,low,high);
    if(arr[m]>arr[high])
        swap(arr,m,high);
    if(arr[m]>arr[low])
        swap(arr,m,low);
    var pivotkey=arr[low];// 此时low已经是三者中的中间值

    var temp=pivotkey;// 替换的方法,而非交换的方法
    while (low<high){
        while (low<high&&arr[high]>=pivotkey){high--;}

        //swap(arr,high,low); // 交换的方法
        arr[low]=arr[high]; //采用替换的方法

        while (low<high&&arr[low]<=pivotkey){low++;}

        //swap(arr,low,high);
        arr[high]=arr[low]; // 替换的方法
    }
    arr[low]=temp; // 替换的方法
    return low; // 返回枢轴所在位置
}
console.log('快速排序:',QuikSort([50,10,90,30,70,40,60,80,20]));
console.log('快速排序:',QuikSort([2]));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值