排序算法——快速排序.net实现 - Go语言中文社区

排序算法——快速排序.net实现


排序算法——快速排序.net实现

基本思想

通过一趟排序将要排序的数据分割成独立的两个部分,一部分的所有数据都比另一部分所有的数据都要小,然后按照此方法对这两部分的数据分别进行快速排序,整个排序的过程可以递归进行,以此将整个数据变成有序的序列。

算法图例

假如我们现在要对“6 1 2 7 9 3 4 5 10 8” 这10个数进行排序,在上一篇中我们采用冒泡排序将相邻元素比对并做调整,这样的结果是要进行很多次比对,而且每次调整局限在两个相邻元素互换位置。而本篇介绍的快速排序采用计算机领域常用的二分法思想,每次排序将数据分为两部分,交换位置也是跳跃式的,从而达到更高效率。具体思路如下:
首先选择一个元素作为基准值,比如选择第一个元素6,第一轮排序的目标是将序列中所有小于基准值的元素放在左边,所有大于基准值的元素放在右边,结果就是 1 2 5 4 3 6 7 9 10 8,第一轮实现思路如下:
我们先用变量“哨兵i”和"哨兵j“分别指向序列最左边和最右边,如下图所示:
在这里插入图片描述
首先哨兵j一步步向左挪动(即j- -),直到找到一个小于基准值6的数停下来,接着哨兵i一步步向右挪动(即i+ +),直到找到一个大于6的数停下。最后哨兵i指向7,哨兵j指向5,此时将两个元素位置交换。
在这里插入图片描述
交换后序列结果是 6 1 2 5 9 3 4 7 10 8
然后哨兵j继续向左,哨兵i继续向右,重复上面的思路,如下:
在这里插入图片描述
然后第二次交换后序列结果为 6 1 2 5 4 3 9 7 10 8。此时我们再重复上面的思路发现哨兵i和哨兵j都指向了数字3,说明交换到了终点,此时我们将基准值6与3对换,结果如下:
在这里插入图片描述
此时我们已经完成了第一轮排序的目标,数字6已经归位,小于6的都在6左边,大于6的都在6右边。此时序列被分为了两部分,然后我们分别从左边的序列(3,1,2,5,4)中选择一个基准值采用快速排序思想对左边的序列进行排序,从右边的序列(9,7,10,8)中选择一个基准值进行快速排序,如此不停分割递归排序,直到所有数都归位即完成了整个序列的排序。

编码实现

public static T[] Quick_Sort<T>(T[] array, int left, int right) where T : IComparable
        {
            if (left>=right)
            {
                return array;
            }
            int i, j;
            T temp = array[left];   //取第一个元素作为基准值
            T t = default(T);
            i = left;   //哨兵i初始指向序列最左边
            j = right;  //哨兵j初始指向序列最右边
            while (i != j)
            {
                //哨兵j向左移动,直到找到第一个比基准值小的停下
                while (array[j].CompareTo(temp) >= 0 && i < j)
                {
                    j--;
                }
                //哨兵i向右移动,直到找到第一个比基准值大的停下
                while (array[i].CompareTo(temp) <= 0 && i < j)
                {
                    i++;
                }
                if (i < j) //如果两个哨兵还没有相遇,则交换位置
                {
                    t = array[i];
                    array[i] = array[j];
                    array[j] = t;
                }
            }
            //将基准值归位
            array[left] = array[i];
            array[i] = temp;
            //对左边和右边的序列分别再进行快速排序
            Quick_Sort<T>(array, left, i - 1);
            Quick_Sort<T>(array, i + 1, right);
            return array;
        }

最终调用及执行结果如下:
在这里插入图片描述

总结分析

在最坏的情况下,快速排序也需要像冒泡排序一样每相邻两个元素都要比较,时间复杂度为O(N2),快速排序平均时间复杂度为O(NlogN)。
然后我们做一个测试,随机生成一个包含十万个数字的数组,分别用冒泡排序和快速排序对比排序所需时间。
测试代码如下:

static void Main(string[] args)
        {
            int[] array1 = new int[100000];
            int[] array2 = new int[100000];
            var rand = new Random();
            for (int i = 0; i < array1.Length; i++)
            {
                var temp = rand.Next(100000);
                array1[i] = temp;
                array2[i] = temp;
            }
            Task.Run(() =>
            {
                Console.WriteLine("冒泡排序开始...");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                SortHelper.MP_Sort<int>(array1);
                stopwatch.Stop();
                Console.WriteLine("冒泡排序结束,十万条数据用时:" + stopwatch.Elapsed.TotalMilliseconds + "ms");
            });
            Task.Run(() =>
            {
                Console.WriteLine("快速排序开始...");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                SortHelper.Quick_Sort<int>(array2,0,array2.Length-1);
                stopwatch.Stop();
                Console.WriteLine("快速排序结束,十万条数据用时:" + stopwatch.Elapsed.TotalMilliseconds + "ms");
            });
            Console.ReadLine();
        }

测试结果如下:
在这里插入图片描述
很明显,在数据量较大情况下,快速排序的平均效率高出冒泡排序多个数量级。

博客新人~如有问题或错误,还望大家在评论中斧正

上一篇: 排序算法——冒泡排序.net实现.

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/Leaderxin/article/details/102613995
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-28 01:45:53
  • 阅读 ( 1300 )
  • 分类:算法

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢