排序的稳定性:相等的几个元素在排序之后,其相对的先后顺序不变,则称该排序算法为稳定的。
排序算法是否为稳定的是由具体算法决定的,
不稳定的算法在某种条件下可以变为稳定的算法,
而稳定的算法在某种条件下也可以变为不稳定的算法。
稳定的排序算法:冒泡排序、插入排序、归并排序、基数排序、统计排序
不稳定的排序算法:选择排序、快速排序、希尔排序、堆排序
内部排序:直接在原数据结构上交换元素的值来达成排序
算法仅针对数值元素排序,某些算法仅适用于非负整数或大于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; }
来源:https://www.cnblogs.com/ecalf/archive/2013/04/15/3022193.html