• 排序算法之快速排序


    算法描述:

        快速排序也使用分治思想,其过程为:

        分解:将原数组划分为两个子数组,但要求左边数组的每个元素都小于右边数组的每个元素。

        解决:通过递归调用快速排序,对子数组进行排序。

        合并:因为子数组是原址排序,所以不需要合并操作。

    快速排序划分数组的方法:

    1. 单方向遍历

       选择最后一个元素为基准元素。记为x。

       定义如下几个计数变量:

       i:闭区间[0, i]内的元素都≤x

       j:开区间(i, j)内的元素都>x,j为遍历使用的变量

       代码解释:每次发现一个≤x的元素,都会放到第一个区间内,即[0,i]区间内,然后j++。

    int divide(int low, int high)
    {
        int x = data[high];
        int i = low - 1;  // 初时<=x的区间为空
    
        // 从第一个元素开始遍历,不包括基准元素
        for(int j = low; j < high; j++)
        {
            if(data[j] <= x)
            {
                // 将该元素放入区间[low, i]
                i = i + 1; // 区间扩大一个元素
                swap(data[i], data[j]);
            }
        }
    
        swap(data[i+1], data[high])
    
        return i + 1;
    }
    

      

    2. 双向遍历

    int divide(int low, int high)
    {
        int x = data[high];
        while(low < high)
        {
            // 从左向右寻找>x的元素
            while(low < high && data[low] <= x) 
            {
                low++;
            }
            data[high] = data[low];
    
            // 从右向左寻找<x元素
            while(high > low && data[high] >= x) 
            {
                high--;
            }
            data[low] = data[high];
        }
        data[low] = x;
        return low;
    }
    

      

    排序算法实现:

    void QuickSort(int low, int high)
    {
        int mid = divide(low, high);
        if(low < high)
        {
            QuickSort(low, mid - 1);
            QuickSort(mid + 1, high);
        }
    }
    

      

    复杂度分析:

       快速排序的时间复杂度依赖于划分是否平衡,而平衡与否又依赖于用于划分的元素。

       如果划分平衡,则其算法性能与归并排序一致,为O(nlgn)。

       快速排序使用的空间是O(1)的,也就是个常数级;而真正消耗空间的就是递归调用导致的栈空间了,因为每次递归就要保持一些数据; 

           最优的情况下空间复杂度为:O(logn); 每一次都平分数组的情况
           最差的情况下空间复杂度为:O(n)

       若每次都选取最大或最小值作为基准,导致两个子问题分别包含了0个元素和n-1个元素,则其时间复杂度是多少呢?

       易知划分算法的时间复杂度为O(n)。

       由递归式知:T(n) = T(n-1) + T(0) + O(n) =  T(n-1) + O(n) = T(n-2) + 2 * O(n) = O(n2)
     

    稳定性分析:

        快速排序是不稳定的排序算法

  • 相关阅读:
    Ducking
    MINITAB(二)
    JFreechart
    linux命令0424
    JAVA哈哈镜
    HTML(四)
    The 3n+1 problem
    [转载]:【读书笔记】.NET本质论
    ER图基本步骤
    [从架构到设计]第一回:设计,应该多一点(转载)
  • 原文地址:https://www.cnblogs.com/yanghh/p/12680091.html
Copyright © 2020-2023  润新知