黑马程序员-快速排序

快速排序

  快速排序时所有排序算法中最高效的一种。

  它采用了分治的思想:先保证列表的前半部分都小于后半部分,然后分别对前半部分和后半部分排序,这样整个列表就有序了。这是一种先进的思想,也是它高效的原因。因为在排序算法中,算法的高效与否与列表中数字间的比较次数有直接的关系,而“保证列表的前半部分都小于后半部分”就使得前半部分的任何一个数从此以后都不再跟后半部分的数进行比较了,大大减少了数字间不必要的比较。

  快速排序(QuickSort)是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以 递归 进行,以此达到整个数据变成有序序列。

  设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程成为 一趟快速排序 。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

  一趟快速排序的算法是:

  1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;

  2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];

  3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]赋给A[i];

  4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的值A[i],将A[i]赋给A[j];

  5)重复地3、4步,知道i=j;(3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[j]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直到找到为止。找到符合条件的值,进行交换的时候i,j指针位置不变。另外,i==j 这一过程一定正好是 i+ 或 j- 完成的时候,此时令循环结束)。

  如果i和j没有碰头的话,就递加i找大的,还没有,就再递减j找小的,如此反复,不断循环。注意判断和寻找是同时进行的。

 

  注意:快速排序不会直接得到最终结果,只会把比k大和比k小的数分到k的两边。(你可以想象一下i和j是两个机器人,数据就是大小不一的石头,先取走i前面的石头留出回旋的空间,然后他们轮流分别挑选比k大和比k小的石头扔给对面,最后在他们中间把取走的那块石头放回去,于是比这块石头大的全扔给了j那一边,小的全扔给了i那一边。只是这次运气好,扔完一次刚好排整齐。)为了得到最后结果,需要再次对下标2两边的数组分别执行此步骤,然后再分解数组,直到数组不能再分解为止(只有一个数据),才能得到正确结果。
 

namespace QuickSort

{

    class Program

    {

        static void Main(string[] args)

        {

            //

            int[] array = { 49, 38, 65, 97, 76, 13, 27 };

            sort(array, 0, array.Length - 1);

            Console.WriteLine(string.Join(",", array));

            Console.ReadLine();

        }

        

        /// <summary>

        /// 一次排序单元,完成此方法,key左边都比key小,key右边都比key大。

        /// </summary>

        /// <param name="array">排序数组</param>

        /// <param name="low">排序起始位置</param>

        /// <param name="high">排序结束位置</param>

        /// <returns>单元排序后的数组</returns>

        private static int sortUnit(int[] array, int low, int high)

        {

            int key = array[low];

            while (low < high)

            {//从后向前搜索比key小的值

                while (array[high] >= key && high > low)

                    --high;//比key小的放左边

                array[low] = array[high];//从前向后搜索比key大的值,比key大的放右边

                while (array[low] <= key && high > low)

                    ++low;//比key大的放右边

                array[high] = array[low];

            }//左边都比key小,右边都比key大。//将key放在游标当前位置。//此时low等于high

            array[low] = key;

            //Console.WriteLine(string.Join(",", array));

            return high;

        }

        /// <summary>

        /// 快速排序

        /// </summary>

        /// <param name="array"></param>

        /// <param name="low"></param>

        /// <param name="high"></param>

        public static void sort(int[] array, int low, int high)

        {

            if (low >= high)

            {

                return;

            }

            else

            {

                int index = sortUnit(array, low, high);//完成一次单元排序

                sort(array, low, index - 1);//对左边单元进行排序

                sort(array, index + 1, high);//对右边单元进行排序

            }

        }

    }

}

 

posted @ 2014-04-16 13:46  己为  阅读(370)  评论(0编辑  收藏  举报