zoukankan      html  css  js  c++  java
  • 快速排序

    快速排序

    快速排序的时间复杂度为O(n2),但其平均性能很好,其期望复杂度为O(nlog2n),并且其中隐含的常数因子很小。

    对输入数组A[p..r],将其划分为两个子数组A[p..q-1]和A[q+1..r],其中A[q]满足,A[q]大于等于任意一个属于A[p..q-1]的元素,小于等于任意一个属于A[q+1..r]的元素。递归划分左右两个子数组,最终就可以得到排序后的数组。其算法如下:

        sort(array)
            sort(array, 0, array.length-1)
        
        sort(array, start, end)
            if start < end
                q = partition(array, start, end)
                sort(array, start, q-1)
                sort(array, q+1, end)

    其中partition分解过程中找到q的位置,其算法如下:

        partition(array, start, end)
            i = start - 1
            for j = start to end-1
                if array[j] <= array[end]
                    i++
                    if i != j
                        exchange array[i] with array[j]
            i++
            exchange array[i] with array[end]
            return i

    partition算法解析:

    (1)将最后一个元素作为主元,由于最开始待划分的两个子数组的大小为0,因此定义分隔位置i的值为start-1,i表示第一个子数组的最后一个元素,而i+1表示分隔的位置。
    (2)围绕主元对start和end-1内的元素进行划分,如果小于等于主元,第一个子数组的大小加1,即分隔位置加1。此时由于a[j]小于主元,因此将其交换到i指示的位置。
    (3)最后,分隔位置加1,此时为第二个数组的第一个位置,将其与主元交换后,这个位置就变成了正确的分隔位置。
    这样在每一次执行partition之后,所有i左侧的元素均小于等于array[i],i右侧的元素大于等于array[i],而array[i]找到了它在数组中的正确位置。

    实例的推导过程(参考《算法导论 第三版》)如下图:

    java实现

    package com.diysoul.algorithm.sort;
    
    import java.util.Random;
    
    public class QuickSort {
    
        public static void sort(int[] array) {
            sort(array, 0, array.length - 1);
        }
    
        public static void sort(int[] array, int start, int end) {
            if (start < end) {
                int p = partition(array, start, end);
                sort(array, start, p - 1);
                sort(array, p + 1, end);
            }
        }
    
        public static int partition(int[] array, final int start, final int end) {
    
            // 增加随机主元,仅测试
            // Random random = new Random();
            // int pos = random.nextInt(end - start + 1) + start;
            // if (pos != end) {
            // int temp = array[end];
            // array[end] = array[pos];
            // array[pos] = temp;
            // }
    
            int i = start - 1;
            for (int j = start; j <= end - 1; j++) {
                if (array[j] <= array[end]) {
                    i++;
                    if (i != j) {
                        int temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
            }
            i++;
            int temp = array[i];
            array[i] = array[end];
            array[end] = temp;
            return i;
        }
    
        public static void main(String[] args) {
            int maxSize = 100;
            int min = -10000;
            int max = 10000;
            Random random = new Random();
    
            int[] a = new int[maxSize];
            for (int i = 0; i < a.length; i++) {
                a[i] = random.nextInt(max - min) + min;
            }
            
            print(a);
            sort(a);
            print(a);
            checkSort(a);
        }
    
        private static void checkSort(int[] array) {
            if (array == null || array.length == 0)
                return;
            for (int i = 1; i < array.length; i++) {
                if (array[i - 1] > array[i]) {
                    System.out.println("Error! Array is not sorted in index " + i);
                    break;
                }
            }
        }
    
        private static void print(int[] array) {
            if (array == null || array.length == 0)
                return;
            System.out.print("quick sort array(" + array.length + "): ");
            int i = 0;
            for (; i < array.length - 1; i++) {
                System.out.print(array[i] + ", ");
            }
            System.out.println(array[i]);
        }
    }
  • 相关阅读:
    Python
    按行读取文本,去重行
    Python字符串---固定长度分割字符串
    python终端打印带颜色的print
    Django安装与删除
    Python拼接字符串的7种方法
    CSS指定标签样式style选择器
    python 使用函数名的字符串调用函数(4种方法)
    test
    字符串常用操作
  • 原文地址:https://www.cnblogs.com/diysoul/p/5673050.html
Copyright © 2011-2022 走看看