快速排序

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

算法步骤:

1 从数列中挑出一个元素,称为 “基准”(pivot),

2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

3 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

实现一趟快速排序的逻辑可以参考:http://jingyan.baidu.com/article/d45ad148905ccf69552b80d9.html

算法关键的点是如何实现“所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面”,这个逻辑。

一趟排序:选取数组的左边第一个元素为基准元素,记录在一个变量里面,然后从右边第一个元素向左搜索,找到一个比基准小的元素j,放到基准元素的位置,这个时候之前j位置为空;再从左向右搜索比基准元素大的元素i,然后将i放到j的位置,最后i==j的时候,将原来记录好的基准元素放到这里,至此一趟排序就完成了。

C#实现:

namespace QuikSort
{
    public class Program
    {
        public static void Main(string[] args)
        {
            int[] arr = { 6, 2, 7, 3, 8, 9, 1, 4, 9, 9, 3, 8, 0, 4, 2 };

            QuikSort(arr, 0, arr.Length - 1);

            Console.Read();
        }

        /// <summary>
        /// 快速排序算法
        /// </summary>
        /// <param name="arr">需要排序的数组</param>
        /// <param name="startIndex">开始的索引</param>
        /// <param name="endIndex">结束的索引</param>
        private static void QuikSort(int[] arr, int startIndex, int endIndex)
        {
            if (startIndex >= endIndex)
            {
                return;
            }
            int balance = Partition( arr, startIndex, endIndex);
            //left
            QuikSort(arr, startIndex, balance - 1);
            //right
            QuikSort(arr, balance + 1, endIndex);
        }

        /// <summary>
        /// 实现一躺快速排序
        /// </summary>
        /// <param name="arr">需要排序的数组</param>
        /// <param name="startIndex">开始的索引</param>
        /// <param name="endIndex">结束的索引</param>
        /// <returns></returns>
        private static int Partition( int[] arr, int startIndex, int endIndex)
        {
            //以第一个元素为平衡点
            int balance = arr[startIndex];
            while (startIndex < endIndex)
            {
                //从右往左搜索
                while (arr[endIndex] >= balance && startIndex != endIndex)
                {
                    endIndex--;
                }
                arr[startIndex] = arr[endIndex];

                //从左往右搜索
                while (arr[startIndex] <= balance && startIndex != endIndex)
                {
                    startIndex++;
                }
                arr[endIndex] = arr[startIndex];
            }
            arr[startIndex] = balance;

            return startIndex;
        }

    }
}
原文地址:https://www.cnblogs.com/La5DotNet/p/6110452.html