zoukankan      html  css  js  c++  java
  • 排序算法——快速排序(高速排序)的代码解读

    此笔记仅作本人学习、复习与思考用。(代码参考网络)

    规定arr[] = {49, 38, 65, 97, 76, 13, 27}

    算法步骤:

    1,选择基点,规定基点 = index(通常选择数组第一个数)

    2,设置left,right(left代表数组最左即arr[0],right代表数组最右即arr[arr.Length - 1],设置left和right是为了向后向前遍历比较和基点的大小)

    3,arr[left] 和 index进行比较,如果arr[left] 大于 index 则放到后面 否则left++ 一直往后找直到找到大于index的值 arr[right] 和 index 进行比较 ,如果arr[right] 小于 index 则放到前面 否则right-- 一直往前找直到找到小于index的值(这样规定的原因取决于这个数组是采取降序排序还是升序排序,现在介绍的升序排序)

    4,将设置的基点index 放入当前的数组中间

    5,重复 2 ,3,4 步骤直到 left == right

    代码示例:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 排序__高速排序
     8 {
     9     class Program
    10     {
    11         public static int[] s = { 49, 38, 65, 97, 76, 13, 27 };
    12         static void Main(string[] args)
    13         {
    14             FastSort(s, 0, s.Length - 1);
    15             Console.ReadKey();
    16         }
    17        
    18         private static int SortUnit(int []arr,int left,int right)
    19         {
    20             int i = left, j = right;
    21             int index = arr[left];
    22             while(left<right)
    23             {
    24                 while (left < right && arr[right] > index) right--;
    25                 arr[left] = arr[right];
    26                 while (left < right && arr[left] <= index) left++;      //   修改
    27                 arr[right] = arr[left];
    28                 
    29             }
    30             arr[left] = index;
    31             foreach (var item in arr)
    32             {
    33                 Console.Write("{0}       ", item);
    34             }
    35             Console.Write("
    ");
    36             return left;
    37         }
    38 
    39         public static void FastSort(int []s,int left,int right)
    40         {
    41             if (left >= right) return;
    42             int index = SortUnit(s, left, right);
    43             FastSort(s, left, index - 1);
    44             FastSort(s, index + 1, right);
    45         }
    46     }
    47 }

    完成排序的片段:

    private static int SortUnit(int []arr,int left,int right)
            {
                int i = left, j = right;
                int index = arr[left];
                while(left<right)           //  @1
                {
                    while (left < right && arr[right] > index) right--;
                    arr[left] = arr[right];
                    while (left < right && arr[left] < index) left++;
                    arr[right] = arr[left];
                    
                }
                arr[left] = index;                           // @2
                foreach (var item in arr)
                {
                    Console.Write("{0}       ", item);
                }
                Console.Write("
    ");
                return left;            //@4
            }
    
            public static void FastSort(int []s,int left,int right)   //@5
            {
                if (left >= right) return;
                int index = SortUnit(s, left, right);
                FastSort(s, left, index - 1);
                FastSort(s, index + 1, right);
            }

    代码解读:

    @1 :该循环是将该数组进行一次排序,排序方式(此处说升序)是 首先从后往前找如果碰到小于index就放到前面,如果不存在这样的数,那么直到left和right相同则停止遍历,从前往后的比较也一样(此处说明一下为什么是先从后往前比较而不是先从前往后比较,这个和选择基点index有关系,因为该例子选择的是数组的第一个元素作为基点index,所以在比较后交换的时候,index就有了保存而不是被覆盖掉,如果要先从前往后比较,那么选择的基点就必须是最后一个元素,这样在arr[right] = arr[left] 赋值的时候,就不会覆盖掉arr[right]原先的值,因为已经被保存

    @2:比较且置换完毕之后,选择将基点作为该数组的中间值,且因为此时left = right 所以 直接返回 left 以便为了切割数组(快速排序是通过分治法即递归来完成排序的,所以需要将原先的数组一分为二,左半边数组重复排序步骤,右半边数组重复排序步骤,直到最终被切割成每个数组的元素只有1个时排序结束)

    @5:递归结束条件就是left = right 即 该数组的长度为1 即 原数组切割完毕,index 表示使的原数组进行一次排序,获得@4的值 更好的重复递归步骤

    PS:这个算法是比较不稳定的,据说有优化的方法,可以使得该方法出现最坏的情况的几率下降,最坏情况是指时间复杂度为O(n2)的情况,有空再研究

    后期优化:在代码标注修改处,从原来的 < 修改成现在的 <= ,原因是当需要排序的数组出现相同的数字的时候,可能会出现死循环的情况的!

  • 相关阅读:
    TWaver3D直线、曲线、曲面的绘制
    react开发教程(六)React与DOM
    java Web开发实现手机拍照上传到服务器
    手把手教你从零写一个简单的 VUE--模板篇
    file_get_contents函数获取不到数据的一种情况
    Windows系统下批处理快速创建WIFI
    操作系统题库之简答题部分(个人整理,附带答案)
    回溯到底是个什么东西(含有大量经典例题加详细分析)
    到底什么是dp思想(内含大量经典例题,附带详细解析)
    一次性弄懂到底什么叫做分治思想(含有大量经典例题,附带详细解析)
  • 原文地址:https://www.cnblogs.com/CHANGKTITI/p/11284032.html
Copyright © 2011-2022 走看看