Hello World

快速排序

1. 快速排序

1.1 排序原理

  • 在数组中找一个分界元素,将数组分为两个区间,小于分界元素的全部放在分界元素之前,其他的放在分界元素之后;
  • 在分出来的两个区间(不包括分界元素)重复上述过程,直到区间缩小为1;

1.2 性能分析

1.2.1 执行效率

  • 最好情况时间复杂度:数据每次分为对等的两个区间,时间复杂度是O(n log n);
  • 最坏情况时间复杂度:数据完全有序,每次元素都分到一个区间,此时时间复杂度是O(n^2);
  • 平均情况复杂度:时间复杂度是O(n^2);

1.2.2  空间复杂度

  每次交换仅需1个临时变量,故空间复杂度为O(1),是原地排序算法。

1.2.3 算法稳定性 

  在定位分界元素时遇到相等的元素不进行位置交换,所以是稳定排序。

1.3 代码实现

   /**
     *
     * @param a 数组对象
     * @param q 数组需要排序区间的开始位置
     * @param p 数组需要排序区间的结束位置
     */
    public static void quickSort(int[] a, int q, int p)
    {
        if (q >= p)
        {
            return;
        }
        /**
         * 将数组分为两部分,index之前的元素都小于a[index],index之后的元素都大于等于a[index];
         * 后面递归处理这两部分,index位置的元素已经确定,后续不再操作a[index]元素
         **/
        int index = findPivotIndex(a, q, p);
        quickSort(a, q, index-1);
        quickSort(a, index + 1, p);
    }

    /**
     *  以游标 i 将 a[q,p] 分为两部分,a[q,i-1] 的元素都是小于分界元素的,称为已处理区间,a[i,p] 的元素为未处理区间;
     *  遍历处理未处理区间的元素;
     *  每次从未处理区间取出一个元素,如果该元素小于分界元素,则将该元素交换到已处理元素区间的末尾,即 a[i] 位置;即将当前元素和 a[i] 元素互换位置;
     *  最后将分界元素和未处理区间的第一个元素交换位置
     * @param a 需要排序的数组对象
     * @param q 需要排序的数组区间的开始位置
     * @param p 需要排序的数组区间的结束位置
     * @return 有序区间的下一个位置下标
     */
    private static int findPivotIndex(int[] a, int q, int p)
    {
        // 取最后一个元素为分界元素
        int pivot = a[p];

        int i = q;
        for (int j = q; j < p; j++)
        {
            if (a[j] < pivot)
            {
                int temp = a[i];
                a[i] = a[j];
                a[j] = temp;
                i++;
            }
        }
        /**
         * 将分界元素交换,此时分界元素的位置就已经确定;
         * 后续的递归处理就不再操作该位置的分界元素,此时该元素已经有序,
         * 前面的元素都小于它,后面的元素都大于等于它
         **/
        a[p] = a[i];
        a[i] = pivot;
        return i;
    }

 

posted @ 2019-03-06 22:27  小小忧愁米粒大  阅读(205)  评论(0编辑  收藏  举报
瞅啥瞅,好好看书