zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    精简的网站reset 和 css通用样式库
    bootstrap使用心得及css模块化的初步尝试
    如何更高效地定制你的bootstrap
    OOCSS的概念和思路
    圣杯布局和双飞翼布局的作用和区别
    espcms简约版的表单,提示页,搜索列表页
    Sublime快捷键
    JavaScript——理解闭包及作用
    JavaScript——基本的瀑布流布局及ajax动态新增数据
    JavaScript——之对象参数的引用传递
  • 原文地址:https://www.cnblogs.com/alias-blog/p/5790745.html
Copyright © 2011-2022 走看看