經典排序算法的 javascript 實現



排序的穩定性:相等的幾個元素在排序之后,其相對的先后順序不變,則稱該排序算法為穩定的。
排序算法是否為穩定的是由具體算法決定的,
不穩定的算法在某種條件下可以變為穩定的算法,
而穩定的算法在某種條件下也可以變為不穩定的算法。
穩定的排序算法:冒泡排序、插入排序、歸並排序、基數排序、統計排序
不穩定的排序算法:選擇排序、快速排序、希爾排序、堆排序

內部排序:直接在原數據結構上交換元素的值來達成排序

算法僅針對數值元素排序,某些算法僅適用於非負整數或大於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;
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM