为了对以下各个算法进行方便的测试,我首先写好了测试主方法体。如下(java实现):

public class Sort {
    public static void main(String[] args) {
        int[] input = { 10, 5, 3, 1, 2 };
        //此处调用方法,以调用冒泡排序为例
        bubbleSort(input);
        for (int i = 0; i < input.length; i++) {
            System.out.println(input[i]);
        }
                                                                                                                                                                                                                                                                                                                                                                                                                           
    }
}


1、冒泡排序(Bubble Sort)时间复杂度:O(n平方)

可以说是最简单的排序方法。这种方法的基本思想是,将待排序的元素看作是竖着排列的气泡,较小的元素比较轻,从而要往上浮。在冒泡排序算法中我们要对这个气泡序列处理若干遍。所谓一遍处理,就是自底向上检查一遍这个序列,并时刻注意两个相邻的元素的顺序是否正确。如果发现两个相邻元素的顺序不对,即的元素在下面,就交换它们的位置。显然,处理一遍之后,最轻的元素就浮到了最高位置;处理二遍之后,次轻的元素就浮到了次高位置。在作第二遍处理时,由于最高位置上的元素已是最轻元素,所以不必检查。一般地,第i遍处理时,不必检查第i高位置以上的元素,因为经过前面i-1遍的处理,它们已正确地排好序。算法示例实现如下(java实现):

public static void bubbleSort(int[] input) {
    for (int i = 0; i < input.length; i++) {
        for (int j = 0; j < input.length - i - 1; j++) {
            if (input[j] > input[j + 1]) {
                int temp = input[j];
                input[j] = input[j + 1];
                input[j + 1] = temp;
            }
        }
    }
}


2、选择排序(Selection Sort)时间复杂度:O(n平方)

选择排序的基本思想是,经过n-i遍历,第一次遍历,选出最小/最大的元素,与排在第一位的元素交换位置;第二次遍历选出第二小/第二大的元素,与第二个元素交换位置;依次类推。算法示例实现如下(java实现):

public static void selectionSort(int[] input) {
        for (int i = 0; i < input.length; i++) {
            int minIndex = i;
            for (int j = i; j < input.length - 1; j++) {
                if (input[minIndex] > input[j + 1])
                    minIndex = j + 1;
            }
            if (minIndex != i) {
                int temp = input[i];
                input[i] = input[minIndex];
                input[minIndex] = temp;
            }
        }
    }


3、插入排序(Insertion Sort时间复杂度:O(n平方)

插入排序基本思想:经过i-1遍处理后,前i-1项己排好序。第i遍处理将第i项插入前i-1项的适当位置,既找到相邻的两个元素x和y,使得input[x]≤input[i]≤input[y],将第i项插入此位置,使得前i项又是排好序的序列。我们可以用顺序比较的方法。首先比较input[i]和input[i-1],如果input[i-1]≤input[i],则[1..i]已排好序,第i遍处理就结束了;否则交换input[i]与input[i-1]的位置,继续比较input[i-1]和input[i-2],直到找到某一个位置j(1≤j≤i-1),使得input[j] ≤input[j+1]时为止。算法示例实现如下(java实现):

public static void insertionSort(int[] input){
    for (int i = 1; i < input.length; i++) {
        for (int j = i; j >0; j--) {
            if (input[j] < input[j-1]) {
                int temp = input[j];
                input[j] = input[j-1];
                input[j-1] = temp;
            }
            else break;
        }
    }     
}


4、快速排序(Quick Sort时间复杂度:O(nlgn)

快速排序基本思想:用数组的首元素作为标准将A划分成前、后两部分,比首元素小的构成前部分,比首元素大的构成后部分,这两部分构成两个新的子问题。通过递归的方式,算法分别对这两个子问题进行排序。算法示例实现如下(java实现):

public static void quickSort(int[] input, int start, int end) {
        int i, j, temp;
        if (start < end) {
            i = start;
            j = end;
            temp = input[start];
            while (i < j) {
                while (i < j && input[j] >= temp)
                    j--;
                while (i < j && input[i] <= temp)
                    i++;
                int exchange = input[j];
                input[j] = input[i];
                input[i] = exchange;
            }
            input[start] = input[j];
            input[j] = temp;
            quickSort(input, start, j - 1);
            quickSort(input, j + 1, end);
        }
    }


5、二分归并排序(Merge Sort时间复杂度:O(nlgn)

二分归并排序基本思想:使用了分治策略。将源数组从中间平分为前后两部分,分别对前后两部分进行排序,排序好的前后两部分数据再归并成源数组。当然对于前后两部分的排序也是使用二分归并排序,这是一个递归的过程。算法示例实现如下(java实现):

public static void mergeSort(int[] input, int start, int end) {
        int middle;
        if (start < end) {
            middle = (start + end) / 2;
            mergeSort(input, start, middle);
            mergeSort(input, middle + 1, end);
            merge(input, start, middle, end);
        }
    }
public static void merge(int[] input, int start, int middle, int end) {
        int[] temp = new int[end - start + 1];
        int i = start, j = middle + 1, n = 0;
        while (i <= middle && j <= end) {
            if (input[i] < input[j]) {
                temp[n] = input[i];
                i++;
            } else {
                temp[n] = input[j];
                j++;
            }
            n++;
        }
        while (i <= middle) {
            temp[n] = input[i];
            i++;
            n++;
        }
        while (j <= end) {
            temp[n] = input[j];
            j++;
            n++;
        }
        for (int x = 0, y = start; x <= n && y <= end; x++, y++)
            input[y] = temp[x];
    }


6、堆排序(Heap Sort时间复杂度:O(nlgn)

堆排序基本思想:首先说一下什么是堆,堆其实是一棵完全二叉树,不过它需要满足堆的性质---父节点大于等于子节点(大顶堆),或者父节点小于等于子节点(小顶堆)。堆排序前首先要构造堆,即要将输入的数组调整成堆(大顶堆为例);然后进行排序,最大堆只能保证首元素是当前堆中最大的元素,我们可以把首元素与堆的最后一个元素互换,这样首元素就排在了最后一个位置,也是正确的位置。然后将堆的前n-1个元素进行排序。互换到首元素位置的元素可能会破坏最大堆的性质,我们调整它使之重新成为最大堆,然后将首元素交换至当前堆的最后一个位置。依次递归。算法示例实现如下(java实现):

public static void heapSort(int[] input) {
        for (int i = input.length / 2; i >= 0; i--)
            adjustHeap(input, i, input.length - 1);
        for (int i = input.length - 1; i >= 0; i--) {
            int temp = input[0];
            input[0] = input[i];
            input[i] = temp;
            adjustHeap(input, 0, i - 1);
        }
    }
public static void adjustHeap(int[] input, int i, int n) {
        int child;
        for (; i <= n / 2;) {
            child = i * 2;
            if (child + 1 <= n && input[child] < input[child + 1])
                child += 1;
            if (input[i] < input[child]) {
                int temp = input[i];
                input[i] = input[child];
                input[child] = temp;
                i = child;
            } else
                break;
        }
    }