对数组进行排序,用时间复杂度最小的排序算法

这个题目是要求对一个数组Array进行排序,要求用时间复杂度最小的排序算法  ----  我们一般选用  快速排序,它的时间复杂度是 O(N LogN)

快速排序采用分区法Partition, 分区法包含如下一些因素:

基准值  --  我们在数组中选择一个基准值(一般选择数组的最后一个值),把数组分成2个区:

                 小于等于基准区域  -- 左边区的元素的值都小于基准值(但是左边区的元素本身是无序的,只是它们的值都比基准值要小).

                 大于基准区域  --  右边区的元素的值都大于基准值(同样,右边区的元素本身也是无序的).

                 基准值    ----  在上面2个区域(【"小于等于基准区域"】  和 【”大于基准区域“】)中间的,就是基准值

边界位置 i  ---  边界位置i 是 【"小于基准区域"】 的最后一个元素的位置  => 由此可以推断出, 基准值的位置就是 i + 1

好了,现在我们按照这个要求来写分区发Partition的代码

   private static int Partition(int[] arr, int left, int right)
   {
       // 为简单起见,直接选择数组最后一个元素作为基准值
       // 比如数组 [3, 1, 4, 2],基准就是 2。
       var pivot = arr[right]; 
       
       // i 指向【"小于等于基准区域"】最后一个元素的位置, 刚开始这个区域还没有建立,所以i = left -1,表示目前【"小于等于基准区域"】为空
       var i = left - 1; 

       //开始遍历数组,最后一个元素arr[right]是基准值,所以不需要遍历它,它不参与数组的遍历
       for(int k = left; k < right; k++)
        {
            //如果当前元素比基准值小,那就把它放入【"小于等于基准区域"】
            if(arr[k] <= pivot)
            {
                i++; //扩大【"小于等于基准区域"】的区域下标

                swap(arr,i,k); //把比基准值小的当前元素,放入【"小于等于基准区域"】的区域尾部
            }
        }


         //遍历完数组后,i指向【"小于等于基准区域"】最后一个元素的位置
         //然后我们要把基准值pivot,也就是arr[right]放到【"小于等于基准区域"】的最后一个位置,也就是i+1的位置
         swap(arr,i+1,right);

         return i + 1; //返回基准值的最终位置
  
    }

 现在我们来写里面用到的swap 工具方法

  // 交换辅助方法
   private static void swap(int[] arr, int x, int y)
   {
        var temp = arr[x];
        arr[x] = arr[y];
        arr[y] = temp;
   }

 

好了,分区Partition方法写好了,我们就可以写递归方法了  --- 递归方法,就是在方法自己内部调用自己

public static void QuickSort(int[] arr, int left, int right)
{
     if(left < right)
     {
// 1. 分区操作,获取基准值的最终位置
var pivotPos = Partition(arr,left,right);
// 2. 递归排序左半部分 QuickSoft(arr,left, pivotPos
- 1);
// 3. 递归排序右半部分 QickSort(arr, pivotPos
+ 1, right); } }

 

所以,最后对数组进行快速排序代码,就是

public static void Sort(int[] arr)
{
     if(arr == null || arr.Length == 1) return;

     QuickSort(arr, 0, arr.Length - 1);
}

 

posted on 2026-09-24 17:47  新西兰程序员  阅读(3)  评论(0)    收藏  举报