排序算法之归并排序

1.算法原理

归并排序(Merge sort)是一种经典的分治算法,它的主要思想是将待排序的数组递归地分成较小的子数组,然后对子数组进行排序,最后再将已排序的子数组合并,直到整个数组有序。

算法的工作原理如下:

分割:将待排序的数组递归地分成较小的子数组,直到子数组只剩下一个元素或为空。
排序:对每个子数组进行排序。可以使用递归地调用归并排序算法进行排序,也可以使用其他排序算法。
合并:将已排序的子数组进行合并,得到完全有序的数组。

2.代码实现(python)

def merge_sort(list):
    if len(list)==1:
        return list
    # 分裂成子列表
    else:
        mid = len(list) // 2
        #左半部分
        left = list[0:mid]
        #右半部分
        right = list[mid:]
        #递归分列合并
        return merge(merge_sort(left),merge_sort(right))
def merge(left,right):
    #定义合并数组
    result=[]
    #开始合并
    while left and right:
        if left[0]<=right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
    #如果左边还有剩余元素,直接添加到结果数组后面
    while left:
        result.append(left.pop(0))
    #如果右边还有剩余元素,直接添加到结果数组后面
    while right:
        result.append(right.pop(0))
    #print(result)
    return result
#测试用例
if __name__ == '__main__':
    lst1 = [1, -2, 234, 23, 56, 23, 12, 324, -2, 0, 321, 38, 239, 89]
    lst2 =[1,2,3,4,5,6,7,8,9,10]
    lst3 =[9, 4, 2, 7, 1, 5, 8, 3, 6]
    print("归并排序")
    print(merge_sort(lst1))
    print(merge_sort(lst2))
    print(merge_sort(lst3))

运行结果

运行结果
这个地方合并的过程,因为是python语言,就比较简便,没有用指针索引的方式来写,两种写法都可以,其原理都是一样的,看个人习惯吧,我把用下标索引来写的函数代码也给出来,方便理解。

def mergeSort(alist):
    if len(alist) > 1:
        mid = len(alist) // 2
        lefthalf = alist[:mid]
        righthalf = alist[mid:]
        #递归调用自身
        mergeSort(lefthalf)
        mergeSort(righthalf)
		#指针索引
        i = j = k = 0
        while i < len(lefthalf) and j < len(righthalf):
            if lefthalf[i] < righthalf[j]:
                alist[k] = lefthalf[i]
                i += 1
            else:
                alist[k] = righthalf[j]
                j += 1
            k += 1

        while i < len(lefthalf):
            alist[k] = lefthalf[i]
            i += 1
            k += 1

        while j < len(righthalf):
            alist[k] = righthalf[j]
            j += 1
            k += 1
#测试用例
if __name__ == '__main__':
	alist = [9, 4, 2, 7, 1, 5, 8, 3, 6]
	mergeSort(alist)
	print(alist)

具体示例

归并排序
如上图所示,把待排序数组一次次分割,直到只剩下一个数为一组;
归并排序2
然后,一一比较再合并,最终变得有序。
合并过程
合并过程
对于这个示例,最后具体合并的过程,如上图:其余的合并过程也是类似的,这样结合起来看代码也就更容易懂了。

3.时空复杂度

时间复杂度:
归并排序的时间复杂度最好、最坏、平均情况都为O(nlogn),其中n是待排序数组的长度。具体分析如下:
分割阶段的时间复杂度是O(logn),因为每次对数组进行二分分割,需要进行logn次递归。
排序阶段的时间复杂度是O(n),因为需要对n个元素进行比较和交换操作。
合并阶段的时间复杂度是O(n),因为需要将n个元素依次合并到一个数组中。
空间复杂度:
归并排序的空间复杂度为O(n),主要是由于需要额外的空间来存储临时数组和递归调用栈。

4.归并排序特点

稳定性

归并排序是一种稳定的排序算法,不会改变数值相同元素之间的相对位置。

优缺点

适用于链表:归并排序对于链表的排序也很有效,因为它的合并操作只需要调整指针,不需要移动元素。
然而,归并排序也有一些缺点
需要额外的空间:归并排序需要额外的空间来存储临时数组,在排序过程中会增加空间的使用。
需要递归调用:归并排序需要使用递归来分割和合并数组,递归调用可能会增加运行时的开销。

与其他算法比较

与其他排序算法相比,归并排序的主要优势是在最坏情况下具有稳定的O(nlogn)时间复杂度。与快速排序相比,归并排序更加稳定,但是在实际应用中可能会有较高的空间需求。与 插入排序冒泡排序 相比,归并排序的时间复杂度更优,但是空间复杂度较高。
总结起来,归并排序是一种高效、稳定的排序算法,时间复杂度为O(nlogn),适用于各种数据类型和数据规模。它的主要缺点是需要额外的空间和递归调用。


文章有不对的地方还请大佬们指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值