排序

from:原文 - git

  • ****冒泡排序****:
    相邻比较大小,交换位置。
  • 快速排序
    快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
    快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 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>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 10,585评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 9,084评论 0 15
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好...
    依依玖玥阅读 5,016评论 0 2
  • 总结一下常见的排序算法。 排序分内排序和外排序。内排序:指在排序期间数据对象全部存放在内存的排序。外排序:指在排序...
    jiangliang阅读 5,228评论 0 1
  • 01. 我是一只非常肥胖的兔子,也许一说到兔子,很多人都是脑海中出现小兔子固有的雪白雪白的身影加上火红火红的眼睛,...
    筱念凉阅读 2,361评论 0 2