排序算法(三)归并排序


一、原理与分析

归并排序法体现了“分治”思想,相较于前面几篇文章讲过的排序算法,归并排序法具有更好的时间复杂度,但是以牺牲部分空间来换取的。

先看图:
图片来自百度

“分治”是将问题划分成逻辑相同,规模更小的子问题,求解子问题后,再将子问题结果合并。归并排序就是将数组分解为两个子数组,将两个子数组排序后在合并排序。对于两个子数组,排序的逻辑与整个数组相同的,因此我们可以用递归求解,当数组长度为1,即只有单个元素时,停止递归。
对于两个数组的合并排序,我们可以用扑克牌来打个比方: 当桌面上有两摞排好序的扑克牌,需要将它们拾起到手中并按大小排好序,我们可以怎么做呢?首先,将两摞扑克牌第一张比较,选取较小的一个拾取,此时被拾取的一摞扑克牌的第一张改变,再将两摞的第一张进行对比……循环此过程,当有一摞扑克牌为空时,直接将另一摞扑克牌全部拿起即可。

二、代码实现

1.将两个子数组合并排序的方法

		static int[] Sort(int[] arrLeft, int[] arrRight)
        {
            int[] array = new int[arrLeft.Length + arrRight.Length];

            int i = 0, j = 0, index = 0;
            while (i < arrLeft.Length || j < arrRight.Length)
            {
                if (i >= arrLeft.Length)
                {
                    while (j < arrRight.Length)
                    {
                        array[index] = arrRight[j];
                        index++;
                        j++;
                    }
                }
                else if (j >= arrRight.Length)
                {
                    while (i < arrLeft.Length)
                    {
                        array[index] = arrLeft[i];
                        index++;
                        i++;
                    }
                }
                else
                {
                    if (arrLeft[i] <= arrRight[j])
                    {
                        array[index] = arrLeft[i];
                        i++;
                    }
                    else
                    {
                        array[index] = arrRight[j];
                        j++;
                    }
                    index++;
                }
            }

            return array;
        }

2.将数组分解并递归排序的方法

		static int[] Merge(int[] array)
        {
            if (array.Length <= 1)
                return array;
            int mid = array.Length / 2;
            int[] arrLeft = new int[mid];
            int[] arrRight = new int[array.Length - mid];

            //将数组拆分成两个部分填入左右两个数组中
            for (int i = 0; i < array.Length; i++)
            {
                if (i < mid)
                    arrLeft[i] = array[i];
                else
                    arrRight[i - mid] = array[i];
            }

            return Sort(Merge(arrLeft), Merge(arrRight));
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值