快速排序之三位中值法

1.  三位取中法原理:

(1)取数组的首中尾位置的元素进行

(2)对首中尾三个位置的元素按照顺序排序

(3)将排好顺序地中位元素放到数组的倒数第二的位置

(4)下界指针从左侧第二个开始找比基准元素大的,找到停止,再从倒数第三个数开始找比基准元素小的,找到停止,交换上界指针和下界指针指向的  值,继续从左侧开始比较,依次循环,直到指针相遇,判断当前相遇值是否大于基准元素,若大于基准元素将,相遇时指针指向的值与倒数第二个值交换,此时数组被分成两部分,左侧全部比基准值小,右侧全部比基准值大。

(5)对左侧和右侧两部分分别各自执行(2),(3),(4)步骤,直到全部比较完成,完成排序

2.  三位中值法图表演示

     

 3.  C#代码实现

    class Program
    {
        static void Main(string[] args)
        {
            // 待排序数组
            int[] sortArray = { 5, 8, 3, 2, 9, 1, 4, 7, 6 };
            Stopwatch sw = new Stopwatch();
            // 开始计时
            sw.Start();
            //  三位取中法
            MiddleQuickSort(sortArray, 0, sortArray.Length - 1);
            // 计时结束
            sw.Stop();
            Console.WriteLine("快速排序方法耗时(毫秒)=" + sw.ElapsedMilliseconds);
        }
        private static void MiddleQuickSort(int[] sortArray, int low, int high)
        {
            if (low < high)
            {
                // 将基准元素放到序列末尾,取基准元素位置
                PivotGet(sortArray, low, high);
                int pivot = high - 1;
                int i = low, j = high - 1;
                while (true)
                {
                    while (sortArray[++i] < sortArray[pivot])
                    {
                        // 下界指针移动,若下界指针指向的元素小于基准元素,什么也不做,一直找,直到找到比基准元素大的
                    }
                    while (j > low && sortArray[--j] > sortArray[pivot])
                    {
                        // 上界指针没有与下界指针相遇,找上界指针指向的值大于下界指针指向的值,一直找直至找到
                    }
                    if (i < j)
                    {
                        Change(sortArray, i, j);
                    }
                    else {
                        break;
                    } 
                }
                if (i < high)
                {
                    Change(sortArray, i, high - 1);
                }
                SortShow(sortArray);
                // 对低子表递归排序
                MiddleQuickSort(sortArray, low, i - 1);
                // 对高子表递归排序
                MiddleQuickSort(sortArray, i + 1, high);
            }
        }
        /// <summary>
        /// 将左中右三个值排成有序且把基准元素排到倒数第二的位置
        /// </summary>
        /// <param name="sortArray">待排序数组</param>
        /// <param name="low">下界指针</param>
        /// <param name="high">上界指针</param>
        private static void PivotGet(int[] sortArray, int low, int high)
        {
            int middle = (low + high) / 2;
            // 首尾比较,若首元素比尾元素大则交换
            if (sortArray[low] > sortArray[high])
            {
                Change(sortArray, low, high);
            }
            // 首中比较,若首元素比中间元素大则交换
            if (sortArray[low] > sortArray[middle])
            {
                Change(sortArray, low, middle);
            }
            // 中尾比较,若中间元素比尾元素大则交换
            if (sortArray[middle] > sortArray[high])
            {
                Change(sortArray, high, middle);
            }
            // 将中间元素与倒数第二元素交换,将中间元素排到倒数第二的位置
            Change(sortArray, high - 1, middle);
        }
        /// <summary>
        /// 交换两个值
        /// </summary>
        /// <param name="sortArray">待排序数组</param>
        /// <param name="low">下界指针</param>
        /// <param name="high">上界指针</param>
        private static void Change(int[] sortArray, int a, int b)
        {
            int temp = sortArray[a];
            sortArray[a] = sortArray[b];
            sortArray[b] = temp;
        }
        private static void SortShow(int[] sortArray)
        {
            for (int i = 0; i < sortArray.Length; i++)
            {
                Console.Write(sortArray[i] + " ");
            }
            Console.WriteLine();
        }
    }

  4.  运行结果

猜你喜欢

转载自www.cnblogs.com/suxiuyan/p/12624266.html