zoukankan      html  css  js  c++  java
  • 经典排序算法的 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;
    }
  • 相关阅读:
    输入框正则表达式验证
    MySQL表名、列名区分大小写详解
    前后台交互
    分页写法
    web程序调试方法
    html 标签
    Aborting commit: 'XXXXXXXX'remains in conflict错误
    返回按钮
    跳出frameset框架
    fastadmin中关联表时A为主表,想让B表和C表关联时怎么办?
  • 原文地址:https://www.cnblogs.com/ecalf/p/3022193.html
Copyright © 2011-2022 走看看