排序算法浅析(一)快速排序

一、概述
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。该方法的基本思想为:

  1. 先从数列中取出一个数作为基准数。
  2. 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
  3. 再对左右区间重复第二步,直到各区间只有一个数。
    以升序为例,其执行流程可概括为:
    每一趟选择当前所有子序列中的一个关键字(通常是第一个)作为枢轴,将子序列中比枢轴小的移到枢轴前边,比枢轴大的移到枢轴后边;当本趟所有子序列都被枢轴以上述规则划分完毕后会得到新的一组更短的子序列,它们将成为下一趟划分的初始序列集。
    二、算法实现
/*快速排序*/
public static void QuickSort(int[] nums,int low, int high){
     int temp;
     int i = low, j= high;
     //判断该排序是否已经完成
     if(low < high){
         temp = nums[low];
         //开始一趟排序,将数组中小于temp的关键字放在左边,大于temp的关键字放在右边
         while(i < j){
             //从右往左扫描,找到一个小于temp的关键字
             while(i < j && nums[j]>=temp)j--;
             /**
              * 疑问一:原来nums[i]的数是哪一个?
              * 解读:首先初始时 i 和 low 是同一个数,已经将该数对应的数组值存在 temp 中,
              * 因此我们是从后往前遍历,查找是否有小于 temp 的数,找到后将其置于 i 对应的位置,
              * 再将其i++
              * */
             if(i < j){
                 nums[i] = nums[j];
                 i++;
             }
             /**
              * 根据上述结论,我们得出目前所空的位置即为 j 所代表的数组值
              * 所以现在是从前往后遍历,查找是否有大于 temp 的数,找到后将其置于 j 对应的位置
              * 再将j--
              */
             while(i < j && nums[i] < temp)++i;
             if(i < j){
                 nums[j] = nums[i];
                 j--;
             }
             /**
              * 此时i的位置又可以存数了,
              * 开始新一轮循环,知道i < j 不成立为止
              * 最后比 temp 小的数都会在 i 的左边,比 temp 大的数都会在 i 的右边
              * 此时就是temp的最终位置
              * */
         }
         nums[i] = temp;
         QuickSort(nums, low, i - 1);
         QuickSort(nums, i + 1, high);
     }
}

三、算法性能分析
(1)时间复杂度分析
快速排序最好情况下的时间复杂度为O(nlog2n),待排序列越接近无序,本算法效率越高。最坏情况下的时间复杂度为O(n的平方),待排序列越接近有序,本算法效率越低。平均情况下时间复杂度为O(nlog2n)。
(2)空间复杂度分析
快速排序的空间复杂度为O(log2n)。快速排序是递归进行的,递归需要栈的辅助,要增加栈的空间。

posted @ 2020-12-11 11:10  Deadwjlee  阅读(198)  评论(0)    收藏  举报