归并排序(C#)

归并排序(C#)【时间复杂度O(N*logN),空间复杂度O(N)】

算法思路(递归)
1、找出数组中间值mid,将数组分为左右两部分[start,…,mid,…,end]
2、将左侧数组排好序
3、将右侧数组排好序
4、左右数组合并(归并)

归并做法:
—开一个辅助空间(与原数组等规模)
—让左侧数组第一个(设L1)和右侧数组第一个(R1)进行比较
若L1<=R1,将L1拷贝到辅助空间第一位(设K1),L1向后移一位到L2,辅助空间也向后移一位到K2,R1不动。继续比较L2与R1…
若L1>R1,将R1拷贝到辅助空间第一位(设K1),R1向后移一位到R2,辅助空间也向后移一位到K2,L1不动。继续比较L1与R2…
哪侧越界(左侧数组界限<=mid,右侧数组界限<=end),就把剩下的部分拷贝到辅助空间。
最后将辅助空间拷贝回原来数组,排序完成。

归并步骤举例:
数组arr[5]={3,2,1,5,6,2}
找到中间位置,且左右两侧都排好序后,此时数组状态为
1,2,3 | 2,5,6

此时L1=1,R1=2.比较L1<R1,将L1的值赋给K1,L1++,K1++;
L2=2,R1=2,L2=R1,将L2的值赋给K2,L2++,K2++;
L3=3,R1=2,L3>R1,将R1的值赋给K3,R1++,K3++;
L3=3,R2=5,L3<R2,将L3的值赋给K4,L3++,K3++;
此时L3++越过了左侧数组的边界
直接将右侧数组剩下的数拷贝到辅助空间中即可。

归并排序实质:没有浪费比较信息,每一次比较行为变为有效的东西,向下传递。

C#代码实现

 public void process(int[] arr,int start,int end)
        {
    
    
            if (start == end)
                return ;
            int mid = start + ((end - start) >> 1);
            process(arr,start,mid);
            process(arr,mid+1,end);
            Merge(arr,start,mid,end);
        }

        public void Merge(int[] arr, int start, int mid, int end)
        {
    
    
            int[] help = new int[end-start+1];//每次help数组长度一定要是end-start+1,因为help若是与arr一样大,会把还未排序的数刷成0(下方复制过程中),这样就失去的未排序的数
            int i = 0;
            int p1 = start;
            int p2 = mid + 1;
            while (p1 <= mid && p2 <= end)
            {
    
    
                help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
            }
            //做完上个循环后此时一定有一边越界
            while (p1 <= mid)//左侧没有越界,右侧越界,将左侧剩下的直接复制到help中。
            {
    
    
                help[i++] = arr[p1++];
            }

            while (p2 <= end)//左侧越界,右侧没越界,将右侧剩下的直接复制到help中
            {
    
    
                help[i++] = arr[p2++];
            }
            //下面数组长度一定要是help数组长度,因为在递归中,help的长度的数组才是有序的,剩下没处理的是无序的.数组复制到arr是要复制道arr的start——end区域
           Array.Copy(help,0,arr,start,help.Length);
           //for (int j = 0; j < help.Length; j++)
              // arr[start+j] = help[j];
        }

该算法时间复杂度可使用Master表达式来求
T(N)=2T(N/2)+O(N)
即a=2,b=2,d=1
log(a)b=1=d
所以时间复杂度O(N
logN)

如有问题,欢迎留言讨论(๑•ᴗ•๑)♡

猜你喜欢

转载自blog.csdn.net/weixin_51565051/article/details/129828234