《算法》2.1-初级排序算法

1. 基本规则

  1. 排序类算法模板
public class Example
{
    public static void sort(Comparable[] a)
    {
        /* See Algorithms 2.1, 2.2, 2.3, 2.4, 2.5, or 2.7. */ }

    private static boolean less(Comparable v, Comparable w)
    {
        return v.compareTo(w) < 0;
    }

    private static void exch(Comparable[] a, int i, int j)
    {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    private static void show(Comparable[] a)
    { // Print the array, on a single
        // line.
        for (int i = 0; i < a.length; i++)
            StdOut.print(a[i] + " ");
        StdOut.println();
    }

    public static boolean isSorted(Comparable[] a)
    { // Test whether the array
        // entries are in order.
        for (int i = 1; i < a.length; i++)
            if (less(a[i], a[i - 1]))
                return false;
        return true;
    }

    public static void main(String[] args)
    { // Read strings from standard
        // input, sort them, and print.
        String[] a = In.readStrings();
        sort(a);
        assert isSorted(a);
        show(a);
    }
}
  1. Comparable接口
    实现了Comparable接口的数据类型:Integer、String、Double都实现了Comparable接口。创建自己的数据类型时,我们也要实现Comparable接口就能使用该模板进行排序。必须要实现Comparable接口中的compareTo方法。
public class Date implements Comparable<Date>
{
    private final int day;
    private final int month;
    private final int year;
    public Date(int d, int m, int y)
    {
        day = d;
        month = m;
        year = y;
    }
    public int day() {return day;}
    public int month(){return month;}
    public int year(){return year;}
    public int compareTo(Date that)
    {
        if (this.year > that.year)
            return +1;
        if (this.year < that.year)
            return -1;
        if (this.month > that.month)
            return +1;
        if (this.month < that.month)
            return -1;
        if (this.day > that.day)
            return +1;
        if (this.day < that.day)
            return -1;
        return 0;
    }
    public String toString()
    {
        return month + "/" + day + "/" + year;
    }
}

compareTo必须实现一个全序关系:
①自反性:对所有的v=v
②反对称性:对所有v<w都有v>w,且v=w时w=v
③传递性

  1. 排序成本模型:比较次数和访问数组的次数
  2. 额外的内存使用

2. 选择排序

  1. 思想
    首先,找到数组中最小的元素,其次将它和数组的第一个元素交换位置。再次,在剩下的元素中找到最小的元素和数组的第二个元素交换位置。如此往复,直到将整个数组排序。不断选择剩余元素中的最小者。
public class Selection
{
    public static void sort(Comparable[] a)
    {
        int N=a.length;
        for(int i=0;i<N;i++)
        {
            int min=i;
            for(int j=i+1;j<N;j++)
                if(less(a[j],a[min])) min=j;
            exch(a,i,min);
        }
    }
}
  1. Example

    选择排序

  2. 分析:
    ①运行时间和输入无关
    ②数据移动是最少的
    ③长度为N的数组需要交换N次,比较次数:(N-1)+(N-2)+...1=N(N-1)/2~![](http://chart.googleapis.com/chart?cht=tx&chl= N^2/2)

3. 插入排序

  1. 思想
    想象打扑克牌,一张一张地把牌插入到适当地位置。在计算机的视线中,为了要给插入的元素腾出空间,我们需要将其余所有元素在插入之前都向后移动一位。插入排序所需要的时间取决于输入元素中的初始顺序。
public class Insertion
{
    public static void sort(Comparable[] a)
    {
        int N=a.length;
        for(int i=1;i<N;i++)
        {   //a[i]插入到a[i-1] a[i-2]...1中
            for(int j=i;j>=0&&less(a[j],a[j-1]);j--)
            {
                exch(a,j,j-1);
            }
        }
    }
}
  1. Example
    插入排序
  2. 分析:
    ①best:输入顺序增大,无需移动元素,只需要N-1次比较。
    ②worst:输入是逆序的:N2/2次比较和交换
    ③平均:N2/4次比较和交换

4. 希尔排序

  1. 思想:
    基于插入排序的快速排序算法。对于大规模乱序的数组插入排序很慢,是因为它只会交换相邻的元素,因此元素只能一点一点移动。希尔排序改进了插入排序算法,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。 关键:使数组中任意间隔为h的元素都是有序的
public static void sort(Comparable[] a) {
        int n = a.length;
        // 3x+1 increment sequence:  1, 4, 13, 40, 121, 364, 1093, ... 
        int h = 1;
        while (h < n/3) h = 3*h + 1; 
        while (h >= 1) {
            // h-sort the array
            for (int i = h; i < n; i++) {
                  //将a[i]插入到a[i-h],a[i-2*h],a[i-3*h].....
                for (int j = i; j >= h && less(a[j], a[j-h]); j -= h) {
                    exch(a, j, j-h);
                }
            }
            assert isHsorted(a, h); 
            h /= 3;
        }
        assert isSorted(a);
}
  1. Example
    希尔排序
  2. 分析:
    希尔排序是基于插入排序的一种算法, 在此算法基础之上增加了一个新的特性,提高了效率。希尔排序的时间复杂度与增量序列的选取有关,希尔排序时间复杂度的下界是n*log2n。希尔排序没有快速排序算法快 O(n(logn)),因此中等大小规模表现良好,对规模非常大的数据排序不是最优选择。但是比O( n^2 )复杂度的算法快得多。并且希尔排序非常容易实现,算法代码短而简单。 此外,希尔算法在最坏的情况下和平均情况下执行效率相差不是很多,与此同时快速排序在最坏的情况下执行的效率会非常差。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,738评论 0 33
  • Java经典问题算法大全 /*【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子...
    赵宇_阿特奇阅读 1,852评论 0 2
  • 【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔...
    叶总韩阅读 5,129评论 0 41
  • 受伤恢复得那么快是因为每次都有人来治愈自己,渐渐地贪恋了这种不靠自己就想忘掉上一段感情的方法。可是,从未想到,会遇...
    十七姑娘诶阅读 507评论 1 1
  • 九曲黄河第一湾的壮阔,让在城市森林中憋屈久了的人瞬间释放,在壮丽的九曲十八弯骑马放歌,荡气回肠,自驾旅行的意义,大...
    耕天下阅读 609评论 0 1