《Algorithms算法》笔记:元素排序(1)——简单排序

《Algorithms算法》元素排序(1)——简单排序


1.排序问题

排序问题在日常生活中非常常见,例如最简单的,学生名单,就有多种排序,名字,成绩,号码,宿舍号……

Alt text

问题是,我们如何对多种类型进行排序?

  • 答案是——回调函数。

它的实现思路很简单: 我们调用系统的sort函数,系统根据需要通过回调对象的CompareTo函数,对特定的对象进行排序。

Alt text

1.1 回调函数

在不同的语言中,有不同的实现回调函数的方式,其中java使用的是Interfaces

这里写图片描述

1.2Java中回调函数的路线图

Alt text

1.3 全序

设集合X上有一全序关系,如果我们把这种关系用 ≤ 表述,则下列陈述对于 X 中的所有 a, b 和 c 成立:

  • 如果 a≤b 且 b≤a 则 a=b (反对称性)
  • 如果 a≤b 且 b≤c 则 a≤c (传递性)
  • a≤b 或 b≤a (完全性)

这里写图片描述

注意: double 的 ≤ 不是全序

1.4 Comparable API

1.4.1 实现原则

  • 必须是全序
  • 小于,等于,大于分别返回负数(-1),0, 正数(1)
  • 对于不兼容的类型,抛出异常

Alt text

1.4.2 例子

Alt text

2个比较有用的排序抽象 :

  • 小于
  • 交换

这两个功能在排序上用处很多

Alt text

2.选择排序

2.1选择排序思想(动画)

选择排序是很简单的思想:
选择最小的和第一个数交换,第二小的的跟第二个数交换……

Alt text

2.2选择排序的内部循环不变性

Alt text

2.3选择排序代码

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);
      }
   }
   private static boolean less(Comparable v, Comparable w)
   {  
/* as before */
  }
   private static void exch(Comparable[] a, int i, int j)
   {  
/* as before */
  }
}

3.插入排序

3.1插入排序思想(动画)

插入排序算法思想也很简单:
每来一个数,把他插入到前面对应的位置,使得前面一直有序
Alt text

3.2插入排序的内部循环不变性

Alt text

3.3插入排序代码

public class Insertion
{
   public static void sort(Comparable[] a)
   {
      int N = a.length;
      for (int i = 0; i < N; i++)
         for (int j = i; j > 0; j--)
            if (less(a[j], a[j-1]))
               exch(a, j, j-1);
            else break;
   }
   private static boolean less(Comparable v, Comparable w)
   {  
/* as before */
  }
   private static void exch(Comparable[] a, int i, int j)
   {  
/* as before */
  }
}

3.4 插入排序分析

插入排序最好的情况是比较N-1次0次交换,最坏的情况要N22次比较和N22次交换

这里写图片描述

插入排序对于部分有序的数组效率挺高的,特别是对于小数组

这里写图片描述

posted @ 2016-04-06 21:58  voidsky  阅读(347)  评论(0编辑  收藏  举报