剖丁解牛式的快速排序分析

剖丁解牛式的快速排序分析

        /// <summary>
        /// 分拆,以第一个数为pivot,找到它应该在的位置(比它大的在它的右侧,比它小的在它的左侧)
        /// </summary>
        /// <param name="col">要排序的数组</param>
        /// <param name="left">范围的开始端</param>
        /// <param name="right">范围的结束端</param>
        /// <returns>分割好后,返回pivot的位置,由于下一步的范围分割</returns>
        private int Div(int[] col, int left, int right)
        {
            //先将pivot取出来,可以看做此位置已经空出来,这样到运作的最后肯定会有一个位置为空,这个空位就是用这个数来填补的。
            //1.如果经过下一步while运算,left不变,最后还是通过col[left]=bases 将抽出的值填回来
            int bases = col[left];
            while (left < right)
            {
                //2.以一往一返为一轮
                //2.1.“往”开始啦,开始扫描,比bases小的吗?如果不测范围缩小“--right”
                while (left < right && col[right] > bases)
                    --right;
                //2.1.1.如果有遇到比bases小的值,交换
                if (left != right)  //如果相等了,说明在这一轮中自己是最小的,也就不用交换,下一个while同理
                {
                    //2.1.2.left vs right 将col[right]填补到开始时空出来位置来的col[left].
                    col[left] = col[right];
                    //2.1.3.如果这一趟交换了,那下一轮就不用再对比了,left变动没关系滴,只要空位right的位置不动就OK
                    left++;                  
                }
                //2.2.“返”开始啦
                while (left < right && col[left] < bases)  //这里的col[left]<bases值得斟酌,为什么要从left,而不是left+1开始?
                    ++left;
                if (left != right)
                {
                    col[right] = col[left];
                    right--;
                }
                //至此完成一轮,接着继续
            }
            col[left] = bases; 
            return left; //这是基准最终停留的位置(由上一段代码可知)
        }
 
        /// <summary>
        /// 快速排序,这里要清楚数组时引用类型
        /// </summary>
        /// <param name="col"></param>
        /// <param name="left"></param>
        /// <param name="right"></param>
        public void QuickS(int[] col, int left, int right)
        {
            int i;
            if (left < right)
            {
                i = Div(col, left, right); //得到分割点,分割点是不用再变动的,经过这一步,它的位置就确定了,快速排序就是以不断地得出分割点的方式来使数组有序起来的。
                QuickS(col, left, i - 1);
                QuickS(col, i + 1, right);
            }
        }
 
 
        //Winform测试代码
        private void button4_Click(object sender, EventArgs e)
        {
            ClientTest();
        }
 
        /// <summary>
        /// 测试
        /// </summary>
        private static void ClientTest()
        {
            QuickSort qs = new QuickSort();
            int[] array = new int[] { 12, 232, 345, 6, 234, 43, 2344, 232, 3, 56, 7898, 23341, 5676, 896 };
            int len = array.Length;
            qs.QuickS(array, 0, len - 1);
            StringBuilder sb = new StringBuilder(12);
            foreach (int item in array)
            {
                sb.Append(item.ToString() + "\t");
            }
            MessageBox.Show(sb.ToString());
        }
posted @ 2012-10-06 13:46  randroid  阅读(197)  评论(0编辑  收藏  举报