快速排序之三位中值法


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.  運行結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM