美文网首页
排序算法

排序算法

作者: bluarry | 来源:发表于2017-12-01 12:22 被阅读0次

一。 初级排序算法


1. 选择排序

(1). 简单描述: 首先找到数组中最小的元素,其次,将它和数组的第一个元素交换位置(如果第一个元素就是最小元素,那么就和自己交换),再次,在剩下的元素中找到最小的元素,将它与数组第二个元素交换。如此往复,直到整个数组有序

(2). 算法实现伪代码

void SelectSort(a[],N){
    for(int i=0;i<N;i++){
        int m=i;
        for(int j=i+1;j<N;j++)
            if(a[j] < a[m]) m=j;
        swap(a,i,m);
    }
}

(3). 复杂度分析

通过分析,对于一个长度为N的数组,0~N-1的任意一个i都会进行1次交换和N-1次比较,因此总共有N次交换以及(N-1)+(N-2)+……+2+1 = N*(N-1)/2 ~ N2/2次比较,时间复杂度为O(n2);

2.插入排序算法

(1). 简单描述:为了给要插入的元素腾出空间,我们需要将其余所有元素插入之前都向右移动一位。

(2). 算法实现伪代码

void InsertSort(a[],N){
    for(int i=0;i<N;i++)
        for(int j=i;j>0 && a[j] < a[i];j--) swap(s,j,j-1);
}

(3). 复杂度分析

对于长度为N且主键不重复的数组,平均情况下插入排序需要 ~ N^2/4 次比较以及 ~ N^2/4次交换,最坏情况下需要 ~N^2/2 次比较和 ~N^2/2 次交换。最好情况下需要 N-1次比较和0次交换

3.希尔排序

(1). 简单描述: 希尔排序为一种改进的插入排序,算法思想为:使数组中任意间隔为h的元素都是有序的,h由大到小,最后必须为1.这样权衡了子数组的规模和有序性,,可改进插入排序.

(2). 实现代码:

void ShellSort(a[],N){
    int h=1;
    while(h<N/3)h=h*3+1;
    while(1){
        for(int i=h;i<N;i++)
            for(int j=i;j>=h&&a[j] < a[j-h];j-=h)
                swap(a[j],a[j+h]);
        h/=3;
    }
}

(3). 算法分析

该算法的数学论证较复杂,和h的选择有密切关系,如使用算法有给出的序列,那么比较的次数不会超出$$N$$的若干倍乘以倍增序列的长度,对于中等大小的数组,它的运行时间是可以接受的,它代码量小,且不需要额外的内存空间。


二。归并排序


1. 思想描述:

首先将数组对半分为两个子数组,递归的利用归并排序完成子数组的排序,然后将两个已排好序的子数组合并即可。

2. 将两个子数组合并算法Merge()实现:

void Merge(a[],lo,mid,hi,b[]){
    int i=lo,j=mid+1;
    for(int k=lo;k<=hi;k++)b[k]=a[k];
    for(int k=lo;k<=hi;k++){
        if(i > mid)             a[k]=b[j++];
        else if(i>hi)           a[k]=b[i++];
        else if(b[j] < b[i])    a[k]=b[j++];
        else                    a[k]=b[i++]; 
    }
}

3. 自顶向下的归并排序实现

1. 算法代码实现

void sort(a[],b[],N){
    mysort(a,0,N-1,b);
}
void mysort(a[],lo,hi,b[]){
    if(hi <=lo ) return;
    int mid=lo+(hi-lo)/2;
    mysort(a,lo,mid);
    mysort(a,mid+1,hi);
    Merge(a,lo,mid,hi,b);
}

2. 复杂度分析:

对于一个长度为N的数组,归并排序需要$$(1/2NlgN)-(NlgN)$$次比较

证明: 令C(N)表示将数组排序是比较次数,显然,C(0)=C(1)=0;通过递归调用mysort, 可得上限为:$$ C(N) <= C(lceil(N/2))+C(lfloor(N/2))+N $$

左边第一项为排序左半部分比较次数,第二项为有半部分的比较次数,第三项为归并是需要的比较次数,比较次数最少为 $$ lfloor(N/2) $$ ,所以下限为 $$ C(N) >= C(lceil(N/2))+C(lfloor(N/2))+ lfloor(N/2) $$

假定 $$ N=2^N $$

3. 几个改进技巧:

  1. 对小规模的数组使用插入排序
  2. 测试数组是否有序
  3. 不复制元素到辅助数


ps:简书不支持数学公式呀。。。凑合看吧

未完,待续。。。(写完时删掉此行)

相关文章

  • java实现快速排序、归并排序、希尔排序、基数排序算法...

    快速排序算法 归并排序算法 希尔排序算法 基数排序算法

  • web开发需要知道的几个算法

    算法分类 快速排序算法 深度优先算法 广度优先算法 堆排序算法 归并排序算法

  • 算法学习(1)-排序算法

    八大排序算法九大排序算法再总结[经典排序算法][集锦][直观学习排序算法] 视觉直观感受若干常用排序算法 快速排序...

  • 经典排序算法总结

    经典排序算法集锦 冒泡法 排序算法入门之冒泡排序 排序算法入门之冒泡排序优化

  • 前端算法学习-第一篇

    冒泡排序算法 冒泡排序算法是最慢的排序算法之一,也是最容易实现的排序算法。之所以叫冒泡排序是因为使用这种算法排序时...

  • 七大排序算法之冒泡排序

    七大排序算法之冒泡排序 @(算法笔记)[排序算法, 冒泡排序, C++实现] 冒泡排序介绍 冒泡排序是七大排序算法...

  • 算法-选择排序

    算 法:选择排序算法时间复杂度: 选择排序算法概述 选择排序伪代码 选择排序实现 选择排序算法概述 排序算法有许...

  • 浅谈排序算法

    排序算法有很多种,今天先谈谈一些简单的排序算法。包括桶排序、冒泡排序和快速排序算法。后期总结各种排序算法。 桶排序...

  • 线性排序

    桶排序、计数排序、基数排序 一、线性排序算法介绍 1.线性排序算法包括桶排序、计数排序、基数排序。2.线性排序算法...

  • 算法4:插入排序和选择排序算法的比较

    排序算法列表电梯: 选择排序算法:详见 《算法4》2.1 - 选择排序算法(Selection Sort), Py...

网友评论

      本文标题:排序算法

      本文链接:https://www.haomeiwen.com/subject/shoibxtx.html