- ****冒泡排序****:
相邻比较大小,交换位置。
- 快速排序:
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,
然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。
一趟快速排序的算法是:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j;
- ****选择排序****:
逐个比较大小,记录最大/小位置,每趟完成后交换本次起始(有序的末尾)和最值。
- ****插入排序****:
样本分为两部分,选取一个作为有序部分,其余为无序部分,无序部分逐个与有序部分比较,放到合适位置。
- ****希尔排序****:
是插入排序的一种更高效的改进版本。
把记录按步长 gap 分组,对每组记录采用直接插入排序方法进行排序。每组第一个作为有序部分,其余后面作为无序部分。
随着步长逐渐减小,所分成的组包含的记录越来越多,当步长的值减小到 1 时,整个数据合成为一组,构成一组有序记录,则完成排序。
image
原文中算法实现,第一个gap中的元素肯定是每一组的有序组组成,所以第一层for从gap后逐个取出元素与它所在组前面的有序部分进行插入排序。
-
归并排序:
归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。而归并的前提的分而治之,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:- 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
- 自下而上的迭代;
使用二分法进行分组,直到最后出现1-1无法再分,这就是1和0比较大小的关系了,开始两两比较进行合并,这时每一次合并都是在有序的基础上进行。逐层向上,左右两组比较合并。
-
堆排序:
和归并排序好相似啊,只不过是不需要归并排序的二分了,直接以二叉树的形式表示,然后再逐层向上。
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
分为两种方法:- 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
- 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
算法步骤 - 根据数据创建一个大顶堆或小顶堆 H[0……n-1];
- 把堆首(最值)和堆尾互换;
- 把堆的尺寸缩小 1;
- 重复步骤 2,直到堆的尺寸为 1。
-
计数排序:
以往的排序算法中,各个元素的位置基于元素直接的比较,这类排序称为比较排序。
而计数排序是基于非排序的思想的,计数排序假设n个输入元素中的每一个都是介于0到k之间的整数。
计数排序的思想是对每一个输入元素x,确定出小于x的元素个数,有了这一信息,就可以把x直接放在它在最终输出数组的位置上。
排序过程:
大体分两部分,第一部分是对输入数据[0,k]范围的n个数逐个统计个数,第二部分是根据有序的个数统计逐个放到有序组:- 声明数组count[k]={0};
- 遍历输入数组input[n],如果input[i]则count[input[i]]++;
- 所以累加count[i]=count[i]+count[i-1]即为小于等于i元素的数字个数;
- 根据累加后个数将input放到output对应位置。
例如:
input:2,0,5,4,3,3,2 --------------n=7,元素个数7
count:0,0,0,0,0,0 ---------------k=5,数据范围[0,5]
count:1,0,2,2,1,1 -----------------对应数值个数
count:1,1,3,5,6,7 -----------------累加
output:0,2,2,3,3,4,5
计数排序同时兼有桶排的高效和快排的霸道
没意思,不看了后两个
桶排序:
基数排序:
<script>
var setObj=new Set();
for(var a=1;a<19;a++){
//console.log(parseInt(Math.random()*10));
setObj.add(parseInt(Math.random()*1000));
}
var arrayObj=Array.from(setObj);
console.log(arrayObj);
function maopao(arrayTmp){
var len= arrayTmp.length;
for(var i=0;i<len;i++){
for(var j=0;j<len-i;j++){
var tmp=0;
if(arrayTmp[j]>arrayTmp[j+1]){
tmp=arrayTmp[j];
arrayTmp[j]=arrayTmp[j+1];
arrayTmp[j+1]=tmp;
}
}
}
}
function xuanzhe(arrayTmp){
var len=arrayTmp.length;
var tmp,minIndex;
for(var i=0;i<len-1;i++){
minIndex=i;
for(var j=i+1;j<len;j++){
if(arrayTmp[i]<arrayTmp[j])
minIndex=j;
}
tmp=arrayTmp[i];
arrayTmp[i]=arrayTmp[minIndex];
arrayTmp[minIndex]=tmp;
}
}
function caru(aTmp){
var len=aTmp.length;
var preIndex,cur;
for(var i=1;i<len;i++){
cur=aTmp[i];
preIndex=i-1;
while(preIndex>=0 && aTmp[preIndex]>cur){
aTmp[preIndex+1]=aTmp[preIndex];
preIndex--;
}
aTmp[preIndex+1]=cur;
}
}
function xier(aTmp){
var len=aTmp.length;
var step=Math.floor(len/2);
for(step;step>0;step=Math.floor(step/2)){
for(var i=step;i<len;i++){
for(var j=i-step;j>=0 && aTmp[j+step]<aTmp[j];j-=step){//因为前面是有序的,所以只存在一次交换
var temp=aTmp[j+step];
aTmp[j+step]=aTmp[j];
aTmp[j]=temp;
}
}
}
}
function guibing(aTmp){
var len=aTmp.length;
if(len < 2)
return aTmp;
var middle=Math.floor(len/2),left=aTmp.slice(0, middle),right=aTmp.slice(middle);
return erfen(guibing(left),guibing(right));
}
function erfen(left, right){
var result=[];
while(left.length && right.length){
if(left[0]<=right[0])
result.push(left.shift());
else
result.push(right.shift());
}
while(left.length)
result.push(left.shift());
while(right.length)
result.push(right.shift());
return result;
}
function kuaisu(aTmp, left, right){
if(left==void(0) && right==void(0)){
left=0;
right=aTmp.length-1;
}
if(left < right){
var pivot2 = yici(aTmp,left,right);
kuaisu(aTmp,left,pivot2-1);
kuaisu(aTmp,pivot2+1,right);
}
}
function yici(aTmp, left, right){
var pivot = aTmp[left];
while(left < right){
while(left < right && aTmp[right] > pivot)
--right;
aTmp[left] = aTmp[right];
while(left < right && aTmp[left] <= pivot)
++left;
aTmp[right] = aTmp[left];
}
aTmp[left]=pivot;
return left;
}
function tiaozhendui(aTmp,len, i){
var largest=i,left=2*i+1,right=2*i+2;
if(left<len && aTmp[left]>aTmp[largest])
largest=left;
if(right<len &&aTmp[right]>aTmp[largest])
largest=right;
if(i!=largest){
swap(aTmp,i,largest);
tiaozhendui(aTmp,len,largest)
}
}
function swap(aTmp,a,b){
var tmp=aTmp[a];
aTmp[a]=aTmp[b];
aTmp[b]=tmp;
}
function buildDui(aTmp){
var len=aTmp.length;
for(var i=Math.floor(len/2);i>=0;i--)
tiaozhendui(aTmp,len,i);
}
function dui(aTmp){
buildDui(aTmp);
var len=aTmp.length;
for(var i=aTmp.length-1;i>0;i--){
swap(aTmp,0,i);
len--;
tiaozhendui(aTmp,len,0);
}
}
function jishu(input){
var MAXvalue=1000;//0-1000范围的整数
var len= input.length;
var count=new Array(MAXvalue+1);
var output=new Array(len);
for(var a=0;a<=MAXvalue;a++)
count[a]=0;
for(var i=0;i<len;i++)
count[input[i]]++;
for(var j=1;j<count.length;j++)
count[j]=count[j]+count[j-1];
for(var k=len-1;k>=0;k--){
output[count[input[k]]-1]=input[k];
count[input[k]]--;
}
return output;
}
//maopao(arrayObj);
//xuanzhe(arrayObj);
//caru(arrayObj);
//xier(arrayObj);
//arrayObj=guibing(arrayObj);
//kuaisu(arrayObj);
//dui(arrayObj);
arrayObj=jishu(arrayObj);
console.log(arrayObj);
</script>
网友评论