归并排序

        /// 
        /// 时间复杂度为O(N)
        /// 
        public static void Merge(int[] arr,int L,int M,int R)
        {
            int[] temp = new int[R - L + 1];
            int i = 0;
            int left_point = L;     
            int right_point = M + 1;

            //左右指针移动,最小的数填充到中间数组
            while (left_point <= M && right_point <= R)
                temp[i++] = arr[left_point] <= arr[right_point] ? arr[left_point++] : arr[right_point++];

            //左或右指针越界时,填充剩余的数
            while (left_point <= M)
                temp[i++] = arr[left_point++];

            while (right_point <= R)
                temp[i++] = arr[right_point++];


            for (i = 0; i < temp.Length; i++)
                arr[L + i] = temp[i];
        }

        /// 
        /// 递归排序 τ(N)=2∗τ(N/2)+ο(N*1)
        /// 
        public static void RecursiveMergeSort(int[] arr,int L,int R)
        {
            if (L == R)
                return;

            int mid = L + ((R - L) >> 1);
            RecursiveMergeSort(arr, L, mid);
            RecursiveMergeSort(arr, mid + 1, R);
            Merge(arr, L, mid, R);
        }

        /// 
        /// 非递归实现 O(N*logN)
        /// 
        /// 
        public static void MergeSort(int[] arr)
        {
            if (arr == null || arr.Length < 2)
                return;

            int N = arr.Length;
            int mergeSize = 1; //当前有序的,左右长度
            while (mergeSize < N)
            {
                int L = 0;
                while (L < N)
                {   
                    int M = L + mergeSize - 1;
                    if (M >= N)
                        break;

                    int R = Math.Min(M + mergeSize, N - 1);
                    Merge(arr, L, M, R);
                    L = R + 1;
                }
                if (mergeSize > N >> 1)
                    break;
                mergeSize <<= 1;
            }
        }

归并排序的核心精髓在于,将比较的行为省下来变为有序的部分,先按最小的范围都先固定好排序(固定的序列中后续不需要做多余的计算),再不断的通过同等级范围进行PK排序进行倍数级扩张范围,直至最终的排序,时间复杂度为

你可能感兴趣的:(归并排序)