第四阶段我们进行深度学习(AI),本部分(第一部分)主要是对底层的数据结构与算法部分进行详尽的讲解,通过本部分的学习主要达到以下两方面的效果:
1.对开发中常见的算法能应用自如,让你在跳槽找工作中“算法题”不再是阻碍你“钱途”的拦路虎。
2.我们不需要调参数的调参攻城狮,我们要做正真的自己的AI模型。
3.本部分预计40篇左右。
hello,大家五一节快乐,今天我们继续聊聊排序算法中比难理解的两种排序算法:快排、归并排序。
为何要把这两个排序放在一起来说呢?主要是基于其时间复杂度都是一致的O(nlogn).
第一、快速排序
快排的思想:如果要排序数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作为pivot(分区点)。
我们遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间。经过这一步骤之后,数组 p 到 r 之间的数据就被分成了三个部分,前面 p 到 q-1 之间都是小于 pivot 的,中间是 pivot,后面的 q+1到 r 之间是大于 pivot 的。
根据分治、递归的处理思想,我们可以用递归排序下标从 p 到 q-1 之间的数据和下标从 q+1 到 r 之间的数据,直到区间缩小为 1,就说明所有的数据都有序了。
我们来看一张图:
好的,没有代码我们只是这样说还是比较理论的,我现在给出大家python版本的快排核心代码:
def _quick_sort_between(a, low, high):
if low < high:
# get a random position as the pivot
# 得到一个任意位置作为支点
k = random.randint(low, high)
a[low], a[k] = a[k], a[low] # 将point 点换到最左边
m = _partition(a, low, high) # a[m] is in final position A[M]处于最终位置
_quick_sort_between(a, low, m - 1)
_quick_sort_between(a, m + 1, high)
def _partition(a, low, high):
pivot, j = a[low], low
print pivot
for i in range(low + 1, high + 1):
if a[i] <= pivot: # 从下标为1的开始找其值小于支撑点则下标自动加1
j += 1
a[j], a[i] = a[i], a[j] # [没有理解] 为了让其[左边的保持有序]?swap # 然后做一次交换(相当于更新了支撑点的下标)
print a
a[low], a[j] = a[j], a[low] # 将支撑点放置在区分左右半区的点上
return j
第二、归并排序
归并排序的核心思想: 如果要排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。
我们看一张图来直观感受一下:
好的,我们还是通过代码来看看归并排序是如何实现的。
def _merge_sort_between(a, low, high):
"""
归并排序
:param a:需排序数组
:param low: 最小下标
:param high: 最大下标
:return:
"""
# The indices are inclusive for both low and high.
# 指数包括低指数和高指数
if low < high:
mid = low + (high - low) // 2 # 求出把数组分成两半的中间节点下标
_merge_sort_between(a, low, mid) # 分解低于mid以下的
_merge_sort_between(a, mid + 1, high) # 分解高于mid的
print(a, low, mid, high)
_merge(a, low, mid, high) # 合并
def _merge(a, low, mid, high):
# a[low:mid], a[mid+1, high] are sorted.
i, j = low, mid + 1
tmp = []
while i <= mid and j <= high:
# i代表左边的半边 j 代表的是右边半边 (若有一边越界则退出,代表已经把一边的排序已经完成)
if a[i] <= a[j]: # 左边第一个与右边第一个比较(若左边小)
tmp.append(a[i]) # 左边的数进入临时排序队列
i += 1 # 左边下标向前移动一位
else: # 若有右边的比左边的小则
tmp.append(a[j]) # 右边的下标向前移动一位
j += 1 # 右边的下标向前移动一位
# 若左边没有越界则开始下标等于左边的剩余下边起点,否则是等于右边下边剩余起点
start = i if i <= mid else j
# 结束结点则用中间节点或者最后一个节点来界定
end = mid if i <= mid else high
tmp.extend(a[start:end + 1]) # 将剩余的有序结点一次性加入有序结点中
a[low:high + 1] = tmp # 重新覆盖传入的无序的列表中
好的,本期我们就说完了排序算法中最为烧脑的两个算法,这个也是在面试中最爱考的两个算法,希望大家认真对待。本期的完整代码请访问我的github自行获取。地址为:https://github.com/haishiniu/Data-Structure-and-Algorithms/tree/master/sorted,如果可以,请大家fork 一下这个代码库,谢谢啦。
本文分享自 python编程从入门到实践 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!