Java数据结构与算法:排序

0.数据有序程度对排序时间的影响

直接插入排序是数据越有序越快,最快时间复杂度可达到O(n),选择排序无论何时都是O(n^2), 快速排序越有序越慢,它要从后到前遍历找比基准小的,时间复杂度达到O(n),堆排序需要不断进行调整,时间复杂度为O(nlog2^n)

1.插入排序

定理:通过交换相邻元素进行排序的任何算法平均都需要>=(N*N)时间。

作为交换相邻元素来排序的一种算法(如冒泡排序、选择排序),其:

  • 最坏时间、平均时间:=(N*N)
  • 最好时间:<=(N*N),即O(N*N)
/**
 * 插入排序,O(N*N)
 * 
 * @param array
 *            数组
 */
public static <AnyType extends Comparable<? super AnyType>> void insertionSort(AnyType[] array) {

    int hole;
    AnyType temp = null;

    for (int i = 1; i < array.length; i++) {
        temp = array[i];
        for (hole = i; hole > 0 && temp.compareTo(array[hole - 1]) < 0;) {
            array[hole] = array[--hole];
        }
        array[hole] = temp;
    }
}

2.希尔排序

希尔排序是对插入排序的改进,但是其时间效率和选择的增量有关,采用希尔增量时最坏时间仍然是=(N*N)。

/**
 * 希尔排序,使用希尔增量,O(N*N)
 * 
 * @param array
 *            数组
 */
public static <AnyType extends Comparable<? super AnyType>> void shellSort(AnyType[] array) {
    int hole;
    AnyType temp = null;

    for (int gap = array.length / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < array.length; i++) {
            temp = array[i];
            for (hole = i; hole >= gap && temp.compareTo(array[hole - gap]) < 0;)
                array[hole] = array[hole -= gap];
            array[hole] = temp;
        }
    }
}

3.堆排序

代码见这里

4.归并排序

  • 在所有流行算法中比较次数最少。
  • 而在Java中,执行一次泛型排序(使用Comparator)时,比较的开销较昂贵,而移动元素是省时的(引用的赋值,不是庞大对象的拷贝),所以是Java中通用排序算法的上好选择。
  • 正是标准Java类库中泛型排序使用的算法。

代码见这里

5.快速排序

  • 使用更少的数据移动,更多使用一些比较。
  • C++的泛型排序中,如果对象庞大,拷贝的开销可能很大,而编译器主动执行内嵌优化,使得比较对象常常相对省时间。
  • C++库中常用这种排序,Java中基本类型的标准库排序也用。

数组S排序的基本算法由4步组成:

  1. 如果S中元素个数小于等于10个,就采用插入排序;
  2. 取S中一个元素为枢纽元素v(推荐使用三数中值分割法);
  3. 把剩下S-1个元素分成两个不相交的集合:S1(元素小于等于枢纽元素),S2(元素大于等于枢纽元素);
  4. 分好后的数组排序为:S1+v+S2。

代码见这里

猜你喜欢

转载自blog.csdn.net/weixin_40255793/article/details/79594813
今日推荐