歸併排序

介紹

歸併排序(MERGE-SORT)是創建在歸併操做上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個很是典型的應用。html

將已有序的子序列合併,獲得徹底有序的序列;即先使每一個子序列有序,再使子序列段間有序。算法

若將兩個有序表合併成一個有序表,稱爲二路歸併。歸併排序是一種穩定的排序方法。數組

佔內存;ide

步驟

1. 申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列;函數

2. 設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置;性能

3. 比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置;spa

4. 重複步驟3直到某一指針超出序列尾;3d

5. 將另外一序列剩下的全部元素直接複製到合併序列尾指針

代碼

        private static void MergeConsole(string location, int[] arr)
        {
            Console.Write($"{location}: ");
            foreach (var i in arr)
            {
                Console.Write("{0}\t", i);
            }
            Console.WriteLine();
        }
        /// <summary>
        /// 歸併數組
        /// </summary>
        /// <param name="arr">要歸併的數組</param>
        /// <param name="left">歸併左序列首元素下標</param>
        /// <param name="mid">拆分元素的下標</param>
        /// <param name="right">歸併右序列最後元素下標</param>
        private static void MergeArray(int[] arr, int left, int mid, int right)
        {
            int[] temp = new int[right - left + 1];
            int m = left, n = mid + 1, k = 0;
            while (n <= right && m <= mid)
            {
                if (arr[m] > arr[n])
                {
                    temp[k++] = arr[n++];
                }
                else
                {
                    temp[k++] = arr[m++];
                }
            }
            while (n < right + 1)
            {
                temp[k++] = arr[n++];
            }
            while (m < mid + 1)
            {
                temp[k++] = arr[m++];
            }
            for (k = 0, m = left; m < right + 1; k++, m++)
            {
                arr[m] = temp[k];
            }
        }
        /// <summary>
        /// 歸併排序
        /// </summary>
        /// <param name="arr">要歸併的數組</param>
        /// <param name="left">歸併左序列首元素下標</param>
        /// <param name="right">歸併右序列最後元素下標</param>
        public static void MergeSort(int[] arr, int left, int right)
        {
            if (left < right)
            {
                int mid = (left + right) / 2;
                MergeSort(arr, left, mid);
                MergeConsole("_left: ", arr);
                MergeSort(arr, mid + 1, right);
                MergeConsole("right: ", arr);
                MergeArray(arr, left, mid, right);
                MergeConsole("merge: ", arr);
                Console.WriteLine();
            }
        }

        static void Main(string[] args)
        {
            int[] array = { 149, 100, 112, 38, 80, 35, 615, 297, 592, 976, 143, 217 };
            MergeSort(array, 0, array.Length - 1);
            Console.ReadLine();
        }
View Code

 

性能分析

 1. 時間複雜度:O(n log n),最好、最壞、平均時間複雜度都是同樣的,由於不關心要排序的數組初始狀態;code

 2. 空間複雜度:O(n),在任意時刻只有一個函數執行,只有一個臨時的內存空間在使用;

 3. 穩定性: 穩定;相同的值能夠選擇是放在左邊仍是右邊的。 

 

 

本文地址:http://www.javashuo.com/article/p-ynymjgoe-dp.html

相關文章
相關標籤/搜索