用python实现经典排序算法

数据管道

共 2972字,需浏览 6分钟

 · 2020-07-28

在正经的笔试题中,排序算法基本不会出现,出现的时候也会作为解题环节的一个小部分。不过,在面试中可能会遇到,毕竟作为数据分析师,难点的可能考你手推公式,简单的可能就说:“来,那你写个快排吧。”
来,那我就奉上我之前使用的部分排序算法的python实现吧,毕竟我是正经算法coding基本撕不出来的人,只能在这种简单算法上使点劲了。

01 冒泡排序

时间复杂度:O(n^2)

算法描述:

比较相邻的元素,如果第一个比第二个大,就交换它们两个;对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;针对所有的元素重复以上的步骤,除了最后一个;重复上述步骤,直到排序完成。

算法实现:

def bubbleSort(alist):    n = len(alist)    for j in range(n - 1):        count = 0          for i in range(n - 1 - j):            if alist[i] > alist[i + 1]:                alist[i], alist[i + 1] = alist[i + 1], alist[i]                count += 1        if count == 0:            break  #提前跳出,提高效率    return alist

02 选择排序

时间复杂度:O(n^2)

算法描述:

首先从未排序的序列中找到最小(大)的元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

算法实现:

def selectSort(alist):    n = len(alist)    for i in range(n):        for j in range(i + 1, n):            if alist[i] > alist[j]:                alist[i], alist[j] = alist[j], alist[i]    return alist

03 插入排序

时间复杂度:O(n^2)

算法描述:

原理是通过构建有序序列,对于未排序数据,在已排序序列中从后往前扫描,找到相应位置并插入。

核心在于把一个无序序列看成两个数列,如第一个元素构成了第一个数列,那剩余元素构成第二个数列,显然第一个数列是有序的(只有一个元素),把第二个数列中的第一个元素拿出来插到第一个数列,使它构成一个有序数列,直到第二个数列中的元素全部插入到第一个数列。

将待插入元素与前一个元素进行比较,若小于,则将前一个元素后移一位,再跟前前一位进行比较,直到遇到小于待插入元素,插入到该位后一位。

算法实现:

def insertSort(alist):    n = len(alist)    for j in range(1, n):        i = j        while i > 0:            if alist[i] < alist[i - 1]:                alist[i], alist[i - 1] = alist[i - 1], alist[i]                i -= 1            else:                break    return alist

04 希尔排序(缩小增量排序)

时间复杂度:O(n^1.3)

算法描述:

是插入排序的优化版,当数据规模较小或数据已基本有序时非常有效。

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序,随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法终止。

算法实现:

def shellSort(alist):    n = len(alist)    t = n // 2    while t > 0:        for i in range(t, n):            j, cur = i, alist[i]            while (j - t >= 0) and (cur < alist[j - t]):                alist[j] = alist[j - t]                j = j - t            alist[j] = cur        t = t // 2    return alist

05 归并排序

时间复杂度:O(nlogn)

算法描述:

先按组拆,拆到都剩单独一个数据为止,再按照拆分的顺序进行合并,小的在前,大的在后,使用左右两个游标进行比较。

分析时间复杂度:因为涉及递归所以不通过代码来看。横向为n次,纵向是除二除二,也就是logn,最坏最好都是nlogn,需要额外空间复杂度。

稳定性:代码中可保证稳定。

算法实现:

def mergeSort(alist):    n = len(alist)    if n <= 1:        return alist    mid = n // 2 #求得列表中间位置    #对左边列表进行归并排序    left_list = mergeSort(alist[:mid])    #对右边列表进行归并排序    right_list = mergeSort(alist[mid:])    #将两个有序的子序列进行合并    left_pointer, right_pointer = 0, 0    result = []    while left_pointer < len(left_list) and right_pointer < len(right_list):        if left_list[left_pointer] < right_list[right_pointer]:            result.append(left_list[left_pointer])            left_pointer += 1        else:            result.append(right_list[right_pointer])            right_pointer += 1    #走到头之后,将剩下的部分直接添加上    result += left_list[left_pointer:]    result += right_list[right_pointer:]    return result

06 快速排序

时间复杂度:O(nlogn)

算法描述:

通过一趟排序将待排记录分隔成独立的两部分,一部分记录的关键字比另一部分的关键字小,则可分别对这两部分继续进行排序,代价是需要额外的内存空间。

算法实现:

def quickSort(alist, first, last):    if first >= last:        return     mid_value = alist[first]    low = first    high = last    while low < high:        #high左移        while low < high and alist[high] >= mid_value:            high -= 1        alist[low] = alist[high]        while low < high and alist[low] < mid_value:            low += 1        alist[high] = alist[low]    #从循环退出时,low=high    alist[low] = mid_value    #对low左边的列表执行快速排序    quickSort(alist, first, low - 1)    #对low右边的列表执行快速排序    quickSort(alist, low + 1, last)


完结。


能力有限,所以我就学习了以上六种排序算法。面试中遇到过冒泡、归并和快排的手写代码考察。笔试中好像排序会经常考察,然而我是真的没学会。你们可不要学我,想进一步学习的可以参考这里(https://b23.tv/yj3k6y)的方法讲述。


友情提示:百分之八九十的数分笔试都会手撕算法coding(数据结构),这方面能力欠缺的同学建议多练习,多思考,别学我。或者抓住提前批(一些公司没有笔试)的机会,还有某些厂笔试不考手撕算法的机会。

浏览 15
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报