Java快速排序

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

算法步骤:

1 从数列中挑出一个元素,称为 “基准”(pivot),

2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

3 基准的位置将数列分为左右两部分,将左右两部分按照上面的步骤重复(递归调用)即可。

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

快速排序详细图解:【坐在马桶上看算法】算法3:最常用的排序——快速排序

算法图示

算法性能

排序算法 平均时间复杂度 最坏时间复杂度 最好时间复杂度 空间复杂度 稳定性
快速排序 O(N*LogN) O(n2) O(N*logN) O(N*logN) 不稳定

Java代码

package com.sort;

import java.util.Random;

public class Main6 {

    private static void sort(int[] array, int begin, int end) {
        if (begin < end) {
            int left = begin;
            int right = end;
            while (left != right) {
                /**
                 * 选取第一个元素作为标杆,即 array[begin]。先从右边往左边搜索,找到比标杆小的
                 */
                while (array[right] >= array[begin] && right > left) {
                    right--;
                }
                /**
                 * 选取第一个元素作为标杆,即 array[begin]。 再从左边往右边搜索,找到比标杆大的
                 */
                while (array[left] <= array[begin] && left < right) {
                    left++;
                }
                /**
                 * 交换left(比标杆大,应该在标杆右边)和right(比标杆小,应该在标杆左边)对应的元素
                 * 这样比标杆大的就在标杆右边,比标杆小的在标杆左边
                 * 
                 * 这里要注意,如果左右没有重合那就交换左右所在的位置的元素,如果左右重合,那就
                 * 交换这个位置和标杆的位置的元素。
                 */
                if (left < right) {
                    int temp = array[left];
                    array[left] = array[right];
                    array[right] = temp;
                }
            }
            /**
             * 当left == right,说明这个已近遍历结束,这时把标杆和这个位置交换,那么标杆就在数组
             * 的中间位置(左边的比标杆小,右边比标杆大)
             */
            int temp = array[left];
            array[left] = array[begin];
            array[begin] = temp;
            /**
             * 继续处理左边的
             */
            sort(array, begin, left - 1);
            /**
             * 继续处理右边的
             */
            sort(array, right + 1, end);
        }
    }

    /**
     * 获取指定长度的随机数组
     */
    public static int[] getRandomArray(int n) {
        int[] array = new int[n];
        Random random = new Random();
        for (int i = 0; i < array.length; i++) {
            array[i] = random.nextInt(500);
        }
        return array;
    }

    /**
     * 打印指定数组
     */
    public static void outputArray(int[] array) {
        for (int i : array) {
            System.out.print(i + " ");
        }
        System.out.println("");
    }

    public static void main(String[] args) {
        int[] array = getRandomArray(10);
        outputArray(array);
        sort(array, 0, array.length - 1);
        outputArray(array);
    }
}
posted @ 2016-08-20 16:44  27House  阅读(253)  评论(0编辑  收藏  举报