算法笔记 7 归并排序和快速排序(上)

微信公众号:珷玞的日常

上一部分笔记是时间复杂度为 O(N^2),比较高,适合小规模数据的排序。今天看两种时间复杂度为 O(nlogn),归并排序和快速排序。

归并排序

归并排序就是一个典型的分而治之思想的算法,核心思想:将序列分为前后两部分,对前后两部分分别排序,然后合并这两部分,得到最后结果。

根据归并的核心思想,我们其实是将排序问题分解为两个子问题:前半部分排序,后半部分排序。这两个子问题又进行分解,最后分解为单独元素之后,进行归并,这也是排序的过程,最后得到结果。

由于归并使用分而治之的思想,所以我们使用递归的方法来实现代码。具体如下:

# 归并排序

def mergeSort(l):

   if len(l) <= 1:

       return l

   else:

       return mergeSortRecursion(l)

# 递归部分,主体部分就是不停的分割合并

def mergeSortRecursion(l):

   head = 0

   tail = len(l) - 1



   if len(l) <= 1:

       return l

   else:

       m = int(len(l)/2)

       l1 = mergeSortRecursion(l[head:m])

       l2 = mergeSortRecursion(l[m:tail+1])

       result = merge(l1,l2)

   return result

# 合并函数,进行两个数组之间的合并

def merge(l,s):

   i = 0

   j = 0

   result = []



   while i<len(l) and j<len(s):

       # 如果 l 的最后一个元素小于 s 的第一个元素,因为 l s 都是有序的,所以直接拼接就可以了

       if l[-1] <= s[j]:

           break

       if l[i] <= s[j]:

           result.append(l[i])

           i += 1

       else:

           result.append(s[j])

           j += 1

   result += l[i:]

   result += s[j:]

   return result



l = [6,5,4,3,2,1]



print([i for i in mergeSort(l)])

分析

  1. 归并排序是稳定的排序算法么?

稳定取决于 merge 函数的比较,我们代码中是小于等于的时候,result 添加 l[i],所以 l 中的元素始终在 s 的元素前边,所以是稳定的。

  1. 归并排序时间复杂度?

时间复杂度为 O(nlogn),由于归并排序的执行效率与要排序的原始数组的有序程度无关,所以时间复杂度很稳定。

快速排序

快速排序也是分而治之思想的一种典型的算法。基本思想:在序列中随意找一个元素为基准,然后遍历其他数据,小于的放在左边,大于的放在右边。

代码实现:

def quick_sort(array, l, r):

   if l < r:

       q = partition(array, l, r)

       quick_sort(array, l, q - 1)

       quick_sort(array, q + 1, r)





def partition(array, l, r):

   x = array[r]

   i = l - 1

   for j in range(l, r):

       if array[j] <= x:

           i += 1

           array[i], array[j] = array[j], array[i]

   array[i + 1], array[r] = array[r], array[i + 1]

   return i + 1

分析

  1. 快速排序是一种稳定的、原地排序

  2. 快速排序的时间复杂度

快速排序的时间复杂度为 O(nlogn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿德罗斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值