快速排序算法

孤街浪徒 提交于 2019-12-03 11:14:25

介绍

快速排序是对冒泡排序的一种改进。

思想:将排序的数据分为两部分,一部分数据所有数据小于另一部分所有数据,然后在分别进行快速排序,排序过程可递归,从而得到有序序列。

它使用分治法(Divide and conquer)策略,把一个串行分为两个子串行。

步骤

1. 从数列中选一个元素,作为“基准”(pivot);

2. 重新排序数列,比基准小的值在左边(left),大的值在右边(right),等值随意;得到两个子数列:left、right;

3. left子数列重复1和2;right子数列重复1和2;递归。

代码

        /// <summary>
        /// 一次排序单元,左边小,右边大
        /// </summary>
        /// <param name="array">排序数组</param>
        /// <param name="left">排序起始位置</param>
        /// <param name="right">排序结束位置</param>
        /// <returns></returns>
        private static int SortUnit(int[] array, int left, int right)
        {
            int pivot = array[left];
            while (left < right)
            {
                // 从后向前搜索比 pivot 小的值
                while (array[right] >= pivot && right > left)
                {
                    --right;
                }
                // 比 pivot 小的放左边
                array[left] = array[right];
                // 从前向后搜索比 key 大的值
                while (array[left] <= pivot && right > left)
                {
                    ++left;
                }
                // 比 pivot 大的放右边
                array[right] = array[left];
            }
            // 左边都比 pivot 小,右边都比 pivot 大
            // 将 pivot 放在游标当前位置。此时 left 等于 right
            array[left] = pivot;
            foreach (var i in array)
            {
                Console.Write("{0}\t", i);
            }
            Console.WriteLine();
            return right;
        }
        /// <summary>
        /// 左边小,右边大
        /// </summary>
        /// <param name="array">排序数组</param>
        /// <param name="left">排序起始位置</param>
        /// <param name="high">排序结束位置</param>
        /// <returns></returns>
        public static void QuickSort(int[] array, int left, int right)
        {
            if (left >= right)
                return;
            // 完成一次单元排序
            int index = SortUnit(array, left, right);
            // 对左边单元进行排序,递归
            QuickSort(array, left, index - 1);
            // 对右侧单元进行排序,递归
            QuickSort(array, index + 1, right);
        }
        static void Main(string[] args)
        {

            #region 快速排序算法
            int[] array = { 149, 100, 112, 38, 80, 35, 615, 297, 592, 976, 143, 217 };
            QuickSort(array, 0, array.Length - 1);
            Console.ReadLine();
            #endregion
        }
View Code

性能分析

算法复杂度

快速排序的性能高度依赖于选择的基准值。

最糟糕的:O(n ^ 2);

  在最糟糕的情况下,栈长O(n),在调用栈的每层都涉及O(n)个元素,完成每层所需的时间都为O(n);O(n) * O(n) = O(n ^ 2);

最佳的:O(n log n);

  在最佳的情况下,中间的元素作为基准值,栈长O(log n);每一层运行时间为O(n);O(n) * O(log n) = O(n log n);

平均的:O(n log n);

  最佳即平均,只要每次都随机地选择一个数组元素作为基准值,快速排序的平均运行时间就将为O(n log n)。

快速排序是最快的排序算法之一。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!