经典排序算法的 javascript 实现

家住魔仙堡 提交于 2020-03-26 00:19:07


排序的稳定性:相等的几个元素在排序之后,其相对的先后顺序不变,则称该排序算法为稳定的。
排序算法是否为稳定的是由具体算法决定的,
不稳定的算法在某种条件下可以变为稳定的算法,
而稳定的算法在某种条件下也可以变为不稳定的算法。
稳定的排序算法:冒泡排序、插入排序、归并排序、基数排序、统计排序
不稳定的排序算法:选择排序、快速排序、希尔排序、堆排序

内部排序:直接在原数据结构上交换元素的值来达成排序

算法仅针对数值元素排序,某些算法仅适用于非负整数或大于0的整数;
在 js 中 undefined 的不等式运算返回 false,
因此有些比较操作执行前没有给变量赋初值也没有检查数组越界,
翻译成其他编程语言时需要注意


算法的描述参考下文 @kkun:
http://www.cnblogs.com/kkun/archive/2011/11/23/2260312.html

addr: http://www.cnblogs.com/ecalf/archive/2013/04/15/3022193.html
author: ecalf

 

有错误和缺陷的地方希望大家指出来

 

//冒泡排序
function BubbleSort(arr){
    for(i=0;i<arr.length;i++){
        for(j=0;j<arr.length-1-i;j++){
            var temp;
            if(arr[j]>arr[j+1]){
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }

    return arr;
}

 

 

 

 

//插入排序
function InsertSort(arr){  
    var  temp;
    for(var i=1,l=arr.length;i<l;i++){ 
        temp = arr[i];
        for(var j=i;j>0;j--){
            if(arr[j-1]>temp){
                arr[j] = arr[j-1];
            }else{                              
                break;
            } 
        }
        arr[j] = temp;   

    }

    return arr;
}

 

//选择排序
function SelectSort(arr){
    for(var i=0,l=arr.length;i<l-1;i++){
        for(var j=i+1;j<l;j++){
            if(arr[j]<arr[i]){
                arr[i] = [arr[j],arr[j]=arr[i]][0];
            }
        }
    }

    return arr;
}

 

 

//快速排序
function QuickSort(arr){
    if(arr.length<=1){    return arr;  }
    var self = arguments.callee;
    var left = [],right = [],middle=[];
    var mid = arr[Math.floor(arr.length/2)];
    for(var i=0;i<arr.length;i++){    
        if(arr[i]<mid){
            left.push(arr[i])
        }else if(arr[i]>mid){
            right.push(arr[i]);
        }else{
            middle.push(arr[i]);
        }
    }

  return [].concat(self(left),middle,self(right));
}

 

//归并排序(2路归并) 
function MergeSort(arr){
    if(arr.length<=1){ return arr;}
    var self = arguments.callee;
    var mid = Math.floor(arr.length/2);
    var left = self(arr.slice(0,mid));
    var right = self(arr.slice(mid));
    var result = [];

    while(left.length&&right.length){
        if(left[left.length-1]<=right[0]){
            result = result.concat(left);
            left = [];            
        }else if(right[right.length-1]<left[0]){
            result = result.concat(right);
            right = [];
        }else{            
            if(right[0]<left[0]){
                result.push(right.shift());
            }else{
                result.push(left.shift());
            }
        }          
    }
    result = result.concat(left,right);

    return result;
}

 

//基数排序(默认10进制),非负整数
function RadixSort(arr,scale){
    scale = scale||10;    
    var max = Math.max.apply(Math,arr);
    var remMask=1,buckets=[],radix;
    while(max>remMask){        
        for(var i=0;i<arr.length;i++){
            radix = Math.floor(arr[i]/remMask)%scale;
            if(!buckets[radix]){
                buckets[radix] = [];
            }
            buckets[radix].push(arr[i]);            
        }

        arr = [];
        for(var k=0;k<buckets.length;k++){
            if(buckets[k]){
                arr = arr.concat(buckets[k]);  
            }        
        }

        remMask *= scale;       
    }
    
    return arr;
}

 

//桶排序,自然数,无重复值
function BucketSort(arr){
    var buckets = [];
    for(var i=0;i<arr.length;i++){
        buckets[arr[i]] = arr[i];
    }
    arr = [];
    for(var i=0;i<buckets.length;i++){
        if(buckets[i]!==undefined){
            arr.push(buckets[i]);
        }
    }

    return arr;
}

 

//鸽巢排序,非负整数
function PigeonholeSort(arr){
    var tempArr = [];
    for(var i=0,l=arr.length;i<l;i++){
        tempArr[arr[i]] = (tempArr[arr[i]]+1)||1 ;
    }

    var result = [],count;
    for(var k=0;k<tempArr.length;k++){
        count = tempArr[k];
        if(count){
            for(var i=0;i<count;i++){
                result.push(k);
            }
        }      
    }

    return result;    
}

 

//希尔排序, fences:分组步长递减,最后一个必须是 1 ,such as [5,3,1]
function ShellSort(arr,fences){
    var half = Math.floor(arr.length/2);
    while(fences.length){        
        var fence = fences.shift();
        if(fence>half){ continue; }

        var tempArr = [];
        while(arr.length){//分组
            for(var i=0;i<fence&&arr.length;i++){
                tempArr[i] = tempArr[i]||[];
                tempArr[i].push(arr.shift());
            }
        }

        
        for(var i=0;i<tempArr.length;i++){  
            //插入排序                      
            for(var k=1,l=tempArr[i].length;k<l;k++){
                var temp = tempArr[i][k];
                for(var j=k;j>0;j--){
                    if(tempArr[i][j-1]>temp){
                        tempArr[i][j] = tempArr[i][j-1];
                    }else{
                        break;
                    } 
                }
                tempArr[i][j] = temp;  
            }
        }
        arr = [].concat.apply([],tempArr);
    }
    return arr;
}

 

//堆排序(2叉树)
function HeapSort(arr){
    var findRoot = function(arr,p,length){
        p = p||0;
        length = length||arr.length;
        var self = arguments.callee;
        var l = p*2+1;
        var r = (p+1)*2;        
        var left,right;
        if(l<length){
            left = self(arr,l,length);
        }
        if(r<length){
            right = self(arr,r,length);
        }

  
        if(left>arr[p]){
            arr[p] = [left,arr[l]=arr[p]][0];
        }

        if(right>arr[p]){
            arr[p] = [right,arr[r]=arr[p]][0];
        }
        
        return arr[p];
    };  
    
    
    for(var i=arr.length;i>0;i--){
        findRoot(arr,0,i);
        arr[i-1] = [arr[0],arr[0]=arr[i-1]][0];
    }    
        
    return arr;
}

 

//奇偶排序
function OddevenSort(arr){
    var swaped = true,k=0;
    while(swaped){
        if(k>0){
            swaped = false;
        }
        
        for(var i=k;i<arr.length-1;i+=2){
            if(arr[i]>arr[i+1]){
                arr[i] = [arr[i+1],arr[i+1]=arr[i]][0];                
                swaped = true;                 
            }            
        }

        k = [1,0][k];
    }

    return arr;
}

 

//鸡尾酒排序
function CocktailSort(arr){
    var swaped = true;
    var l=0,r=arr.length-1;
    while(swaped){
        swaped = false;
        for(var i=l;i<=r;i++){
            if(arr[i]>arr[i+1]){
                arr[i] = [arr[i+1],arr[i+1]=arr[i]][0];
                swaped = true;
            }
        }
        r--;

        for(var i=r;i>l;i--){
            if(arr[i]<arr[i-1]){
                arr[i] = [arr[i-1],arr[i-1]=arr[i]][0];
                swaped = true;
            }
        }
        l--;        
    }
    
    return arr;
}

 

//地精排序
function GnomeSort(arr){
    var i=1;
    while(i<arr.length){        
        if(arr[i]<arr[i-1]){
            arr[i] = [arr[i-1],arr[i-1]=arr[i]][0];
            i = --i||1;
        }else{
            i++;
        }
    }

    return arr;
}

 

//珠排序,自然数
function BeadSort(arr){
    var result = [];
    var beads = [];
    for(var i=0;i<arr.length;i++){
        bead = arr[i];
        while(bead){
            bead--;
            beads[bead] = (beads[bead]||0)+1;
        }
    }

    for(var i=beads[0],l=i;i>0;i--){
        for(var j=0;j<beads.length;j++){
            if(i<=beads[j]){
                result[l-i] = (result[l-i]||0)+1;
            }
        }
    }

    while(arr.length-result.length){
        result.unshift(0);
    }

    return result;
}

 

//统计排序
function CountingSort(arr){
    var count = [];
    for(var i=0;i<arr.length;i++){
        count[i] = count[i]||0;
        for(var j=i+1;j<arr.length;j++){            
            count[j] = count[j]||0;
            if(arr[i]>arr[j]){
                count[i]+=1;
            }else{
                count[j]+=1;
            }
        }
    }
    
    var result = [];
    for(var c=0;c<count.length;c++){
        result[count[c]] = arr[c];
    }

    return result;    
}

 

//圈排序,统计排序的内部排序版本
function CycleSort(arr){
    var count = [];
    for(var i=0;i<arr.length;i++){
        count[i] = count[i]||0;
        for(var j=i+1;j<arr.length;j++){            
            count[j] = count[j]||0;
            if(arr[i]>arr[j]){
                count[i]+=1;
            }else{
                count[j]+=1;
            }
        }
    }
    
    var temp,pos,cycleIndex;
    for(var cycleStart=0;cycleStart<arr.length;cycleStart++){
        if(count[cycleStart]==cycleStart){ continue; }

        temp = arr[cycleStart];
        pos = count[cycleStart];         
        do{
            cycleIndex= pos ;  
            temp  = [arr[pos],arr[pos]= temp][0]; 
            pos = [count[pos ],count[pos ]=pos][0];   
        }while(cycleIndex!=cycleStart);
    }

    
    return arr;    
}

 

 

 

//梳排序
function CombSort(arr){
    var step = arr.length, swaped = true;
    while(swaped||step>1){
        swaped = false;
        if(step>1){
            step = Math.floor(step/1.3);            
        }
        step = step||1;
        
        
        for(var i=0;i+step<arr.length;i++){
            if(arr[i]>arr[i+step]){
                arr[i] = [arr[i+step],arr[i+step]=arr[i]][0];
                swaped = true;
            }
        }
    }

    return arr;
}

 

//耐心排序
function PatienceSort(arr){
    var buckets = [],temp;
    for(var i=0;i<arr.length;i++){
        temp = arr[i];
        for(var j=0;j<buckets.length;j++){
            if(buckets[j][buckets[j].length-1]<=temp){
                buckets[j].push(temp);
                temp = null;
                break;
            }            
        }
        if(temp!==null){
            buckets.push([temp]);
        }
    }
    arr = [].concat.apply([],buckets);
    for(var i=buckets[0].length;i<arr.length;i++){
        for(var j=i;j>0;j--){
            if(arr[j]<arr[j-1]){
                arr[j] = [arr[j-1],arr[j-1]=arr[j]][0];
            }else{
                break;
            }
        }        
    }

    return arr;
}

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!