Python篇——数据结构与算法(第三部分:归并排序;快速、归并、堆排序小结;深拷贝和浅拷贝区别)

 

1、归并排序——归并

  •  假设现在的列表分为两段有序,如何将其合成为一个有序列表
  • 这种操作称为一次归并

 归并过程描述:(前提是两段列表分别有序)

        两段有序列表进行对比,1和2进行对比选出最小的数,1出列,然后指针向后移,2和3在进行对比,2出列,指针向后移,指向5,以此类推......

# 归并排序
def merge(li, low, mid, high):
    '''
    :param li:列表[AB]
    :param low:A列表的第一个位置
    :param mid:A列表的最后一个位置,mid+1为B列表的第一个位置
    :param high:B列表的最后一个位置
    :return:
    '''
    i = low
    j = mid + 1
    ltmp = []  # 临时列表
    while i <= mid and j <= high:  # 只要左右两边都有数
        if li[i] < li[j]:
            ltmp.append(li[i])
            i = i + 1
        else:
            ltmp.append(li[j])
            j = j + 1
    # 第一部分跳出之后,肯定一部分没数了
    while i <= mid:
        ltmp.append(li[i])
        i += 1
    while j <= high:
        ltmp.append(li[j])
        j += 1
    li[low:high + 1] = ltmp


li = [2, 4, 7, 8, 3, 6, 9, 10]
print(li)
merge(li, 0, 3, 7)
print(li)

2、归并排序——使用归并

  • 之前介绍的归并条件是两个列表分别有序,但是在实际中不会遇到这样的特殊情况,因此我们需要进行以下操作
  • 分解:将列表越分越小,直至分成一个元素
  • 终止条件:一个元素是有序的
  • 合并:将两个有序列表归并,列表越来越大
  • 过程如下图所示:

 

# 归并排序
def merge(li, low, mid, high):
    '''
    :param li:列表[AB]
    :param low:A列表的第一个位置
    :param mid:A列表的最后一个位置,mid+1为B列表的第一个位置
    :param high:B列表的最后一个位置
    :return:
    '''
    i = low
    j = mid + 1
    ltmp = []  # 临时列表
    while i <= mid and j <= high:  # 只要左右两边都有数
        if li[i] < li[j]:
            ltmp.append(li[i])
            i = i + 1
        else:
            ltmp.append(li[j])
            j = j + 1
    # 第一部分跳出之后,肯定一部分没数了
    while i <= mid:
        ltmp.append(li[i])
        i += 1
    while j <= high:
        ltmp.append(li[j])
        j += 1
    li[low:high + 1] = ltmp


def merge_sort(li, low, high):
    '''归并排序'''
    if low < high:  # 至少有两个元素
        # 使用递归分解
        mid = (low + high) // 2
        merge_sort(li, low, mid)
        merge_sort(li, mid + 1, high)
        # 使用merge合并
        merge(li, low, mid, high)


# li = [2, 4, 7, 8, 3, 6, 9, 10]
# print(li)
# merge(li, 0, 3, 7)
# print(li)

li = list(range(100))
import random

random.shuffle(li)
print(li)
merge_sort(li, 0, len(li) - 1)
print(li)

3、归并排序算法的时间复杂度和空间复杂度

  • 时间复杂度O(nlogn)
  • 空间复杂度O(n)(递归)

4、基于前两部分的三种排序算法小结

  •  三种排序算法的时间复杂度都是O(nlogn)
  • 一般情况下,就运行时间而言
    • 快速排序<归并排序<堆排序
  • 三种排序算法的缺点:
    • 快速排序:极端情况下排序效率低
    • 归并排序:需要额外的内存开销
    • 堆排序:在快的排序算法中相对较慢

 

 5、深拷贝和浅拷贝的区别

  • 浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存(分支)
  • 深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象,是“值”而不是“引用”(不是分支)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值