首页 > 代码库 > 数据结构与算法-排序算法-partial

数据结构与算法-排序算法-partial

前言

都什么时代了,还写排序算法的总结?

原因有二。一是别人的精彩永远是别人的,你只有鼓掌的份儿;有些事情实际动手去做了才会有所体会。

二是排序算法是一类基础类的算法,不光是IT从业者真正入门的门槛,也是一些高级算法的关键部分或算法评估的benchmark。

计划说明的算法内容有哪些? 

算法的思想、Java代码实现和平均算法复杂度、算法运行完整示例。

参考文献有哪些?

wiki[EB/OL]

Shaffer C. A. Data Structure and Algorithm Analysis in Java, 3rd Edition[M]. Dover Publications, New York. 2011.

 

目录

0 实现工具类

1 插入排序

2 选择排序

3 冒泡排序

4 合并排序

5 堆排序

6 快速排序

7 桶排序

8 基数排序

9 外排序

 

内容

0 实现工具类

//时间费用注解

/**
 * Description: 时间费用注解<br/>
 * Date: 2014-4-26 下午4:49:39
 */
public @interface Expense {
    /** 标记 */
    TAG tag();

    /***/
    String value();

    enum TAG {
        Θ, Ο, Ω
    }
}
View Code

 

//数据结构与算法工具类

package util;

/**
 * 
 *    Description: 数据结构与算法工具类<br/>
 * Date: 2014-5-6 下午10:27:18
 */
public class DSUtil {
    // 单元测试
    public static void main(String[] args) {
        Integer[] A = { 1, 2, 3, 4, 5 };
        println(A);
        swap(A, 1, 3);
        println(A);
    }

    public static Integer[] SORT_TEST_ARRAY = new Integer[] { 42, 20, 17, 13, 28, 14, 23, 15 };

    public static <E> void swap(E[] A, int i, int j) {
        E temp = A[i];
        A[i] = A[j];
        A[j] = temp;
    }

    public static <E> void println(E[] A) {
        for (E a : A) {
            System.out.print(a + " ");
        }
        System.out.println();
    }

}
View Code

 

//排序方法算法接口 - 一般用Integer数组表示待排序列表

package internalsort;

/**
 * Description: 排序方法算法接口<br/>
 * Date: 2014-5-5 下午10:46:52
 */
public interface Sort<E extends Comparable<? super E>> {
    /**
     * Description: 将E元素数组A排序<br/>
     * PRE: <br/>
     * POST: <br/>
     */
    void sort(E[] A);
}
View Code

 

 

1 插入排序

 

package internalsort;

import util.DSUtil;
import util.Expense;

/**
 * Description: 插入排序<br/>
 * 思想:从列表第二个元素开始直到列表末尾,一次将每个元素放置到正确的位置<br/>
 * Date: 2014-5-5 下午10:43:54
 */
public class InsertionSort implements Sort<Integer> {

    /* @see internalsort.Sort#sort(E[]) */
    @Override
    @Expense(tag = Expense.TAG.Θ, value = "http://www.mamicode.com/n^2")
    public void sort(Integer[] A) {
        int n = A.length;
        for (int i = 1; i < n; i++) {//从第二个元素开始,直至列表末尾
            for (int j = i; j > 0; j--) {//从i开始向列表头部,若j处值<j-1处值,交换两者位置
                if (A[j] < A[j - 1]) {
                    DSUtil.swap(A, j, j - 1);
                }
            }
        }
    }

    public static void main(String[] args) {
        InsertionSort service = new InsertionSort();
        Integer[] A = DSUtil.SORT_TEST_ARRAY;

        DSUtil.println(A);
        service.sort(A);
        DSUtil.println(A);
    }
}
View Code

 

 

2 选择排序

 

package internalsort;

import util.DSUtil;
import util.Expense;

/**
 * Description: 选择排序<br/>
 * 思想:从列表头部开始,将当前位置的值与后面的最小值交换<br/>
 * Date: 2014-5-5 下午11:15:30
 */
public class SelectionSort implements Sort<Integer> {

    /* @see internalsort.Sort#sort(E[]) */
    @Override
    @Expense(tag = Expense.TAG.Θ, value = "http://www.mamicode.com/n^2")
    public void sort(Integer[] A) {
        int n = A.length;
        for (int i = 0; i < n - 1; i++) {
            int smallestIndex = i;
            for (int j = i + 1; j < n; j++) {
                if (A[smallestIndex] > A[j]) {
                    smallestIndex = j;
                }
            }
            DSUtil.swap(A, i, smallestIndex);
        }
    }

    //方法1:缺陷交换次数过多
    public void sort1(Integer[] A) {
        int n = A.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                if (A[i] > A[j]) {
                    DSUtil.swap(A, i, j);
                }
            }
        }
    }

    public static void main(String[] args) {
        SelectionSort service = new SelectionSort();
        Integer[] A = DSUtil.SORT_TEST_ARRAY;

        DSUtil.println(A);
        service.sort(A);
        DSUtil.println(A);
    }
}
View Code

 

 

3 冒泡排序

 

package internalsort;

import util.DSUtil;
import util.Expense;

/**
 * Description: 冒泡排序<br/>
 * 思想:第i遍将第i小值排好序<br/>
 * Date: 2014-5-5 下午11:01:56
 */
public class BubbleSort implements Sort<Integer> {

    /* @see internalsort.Sort#sort(E[]) */
    @Override
    @Expense(tag = Expense.TAG.Θ, value = "http://www.mamicode.com/n^2")
    public void sort(Integer[] A) {
        int n = A.length;
        for (int i = 0; i < n - 1; i++) {//遍数标识,共需n-1遍
            for (int j = n - 1; j > i; j--) {//内部循环从列表尾部开始
                if (A[j] < A[j - 1]) {//小元素上升
                    DSUtil.swap(A, j, j - 1);
                }
            }
        }
    }

    public static void main(String[] args) {
        BubbleSort service = new BubbleSort();
        Integer[] A = DSUtil.SORT_TEST_ARRAY;

        DSUtil.println(A);
        service.sort(A);
        DSUtil.println(A);
    }
}
View Code

 

 

4 合并排序

 

 

 

5 堆排序

 

 

 

6 快速排序

 

package internalsort;

import util.DSUtil;
import util.Expense;

/**
 * Description: 快速排序<br/>
 * 思想:将待排序列表按中心点pivot划分为两个子列表,将两个子列表分别排序后再合并<br/>
 * Date: 2014-5-6 下午9:03:56
 */
public class QuickSort {
    static Integer[] A = new Integer[] { 72, 6, 57, 88, 85, 42, 83, 73, 48, 60 };

    public static void main(String[] args) {
        DSUtil.println(A);

        // 测试partition
        // System.out.println(partition(A, -1, A.length - 1, 60));

        // 测试quickSort
        quickSort(A, 0, A.length - 1);
        DSUtil.println(A);
    }

    /**
     * 根据pivot划分A中[l, r]标识的子序列,返回pivot应该放置的位置索引<br/>
     * 此时左边的元素小于pivot,右边的元素大于pivot
     */
    @Expense(tag = Expense.TAG.Θ, value = "http://www.mamicode.com/r-l+1")
    static int partition(Integer[] A, int l, int r, int pivotValue) {
        do {
            // 从小索引开始找值大于pivotValue的
            while (A[++l] < pivotValue);
            // 从大索引开始找值小于pivotValue的
            while ((r != 0) && A[--r] > pivotValue);
            // System.out.println("l=" + l + ", r=" + r);
            DSUtil.swap(A, l, r);
            // DSUtil.println(A);
        } while (l < r);
        // System.out.println("l=" + l + ", r=" + r);
        DSUtil.swap(A, l, r);
        // DSUtil.println(A);
        return l;
    }

    @Expense(tag = Expense.TAG.Θ, value = "http://www.mamicode.com/nlogn")
    static void quickSort(Integer[] A, int i, int j) {
        int pivotIndex = findpivot(i, j);
        DSUtil.swap(A, pivotIndex, j);// 将中心点值放于数组末尾
        int pivotValue =http://www.mamicode.com/ A[j];
        int k = partition(A, i - 1, j, pivotValue);

        DSUtil.swap(A, k, j);// 将中心点值放在正确的位置

        // 递归处理左右子序列
        if ((k - i) > 1) {
            quickSort(A, i, k - 1);
        }
        if ((j - k) > 1) {
            quickSort(A, k + 1, j);
        }
    }

    // 定位中心点,方法1:中间点
    @Expense(tag = Expense.TAG.Θ, value = "http://www.mamicode.com/1")
    static int findpivot(int i, int j) {
        return (i + j) / 2;
    }
}
View Code

 

 

7 桶排序

 

8 基数排序

 

9 外排序