尝试理解一些经典排序算法(python)

排序算法

排序算法,在算法中属于比较重要的。虽然大多数编程语言大都有优化的比较好的排序api,但在真正的开发过程中这些现成的api不一定适合业务的需求。尤其是大数据量的排序时。

排序1—冒泡排序

冒泡排序属于最简单且最常用的算法,也很稳定。但是其时间复杂度并不算突出。

算法描述

  1. 比较相邻的两个元素,如果第一个比第二个大,那么就交换他们两个
  2. 遍历比较每每两个相邻的元素,从第一对都最后一对,这样最大的元素就移到了末尾。
  3. 最大的元素已移到末尾,所以针对除了末尾的所有元素进行第二步操作。
  4. 重复1,2,3操作,直至所有排序完成。

图形展示

在这里插入图片描述

代码实现

def bubble_sort(sort_list):
    for j in range(len(sort_list)-1):
        for i in range(len(sort_list)-1-j):
            if sort_list[i] > sort_list[i+1]:
                sort_list[i], sort_list[i+1] = sort_list[i+1], sort_list[i]
    return sort_list

代码优化

def bubble_sort2(sort_list):
    for j in range(len(sort_list)-1):
        flag = False
        for i in range(len(sort_list)-1-j):
            if sort_list[i] > sort_list[i+1]:
                sort_list[i], sort_list[i+1] = sort_list[i+1], sort_list[i]
                flag = True
        if not flag:
            break
    return sort_list

排序2—选择排序

选择排序属于几种排序中最容易理解的了,也是最常能想到的排序算法。这个算法有一个优点,优点同时也是缺点。就是非常稳定,他的时间复杂度始终是O( n 2 n^2 n2)

算法描述

就是每次比较全部元素,然后把最大最小值放到边边。这样再对长度为n的列表进行了n次遍历之后排序就完成了

图形显示

在这里插入图片描述

代码实现

def selectionSort(sort_list):
    sort_length = len(sort_list)
    for i in range(sort_length):
        min_idx = i
        for j in range(i+1, sort_length):
            if sort_list[min_idx] > sort_list[j]:
                min_idx = j
        sort_list[i], sort_list[min_idx] = sort_list[min_idx], sort_list[i]

    return sort_list

排序3— 插入排序

插入排序(Insertion-Sort)同样也是一种最简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

算法描述

  1. 从第一个元素开始,该元素可以认为已经被排序
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
  5. 将新元素插入到该位置后
  6. 重复步骤2~5

图形显示

在这里插入图片描述

代码实现

def insertionSort(sort_list):
    for i in range(1, len(sort_list)):
        value = sort_list[i]
        insert_index = -1
        for j in range(i-1, -1, -1):
            if value < sort_list[j]:
                sort_list[j+1] = sort_list[j]
                insert_index = j
        if insert_index != -1:
            sort_list[insert_index] = value
    return sort_list

排序4— 希尔排序

希尔排序时对插入排序的一个改进,其排序效率十分可观

算法描述

  1. 将整个待排序的记录序列分割成为若干子序列
  2. 分别进行直接插入排序
  3. 直至所有的排列都是有序的

图形显示

在这里插入图片描述

代码实现

def shell_insert_sort(array, len_array, dk):
    for i in range(dk, len_array):
        position = i
        current_val = array[position]
        _id = i
        j = int(_id / dk)
        _id = _id - j * dk

        while position > _id and current_val < array[position-dk]:
            array[position] = array[position-dk]
            position = position-dk
        else:
            array[position] = current_val


def shell_sort(sort_list):
    dk = int(len(sort_list)/2)
    while(dk >= 1):
        shell_insert_sort(sort_list, len(sort_list), dk)
        dk = int(dk/2)
    return sort_list

排序5— 归并排序

归并排序的设计思想是先把分序列表变得有序,再把两个有序的分列表,合并成一个有序列表

算法描述

  1. 把长度为n的输入序列均分为两个子序列
  2. 对这两个子序列分别排序
  3. 将两个排序好的子序列合并成一个最终的排序序列

图形显示

在这里插入图片描述

代码实现

def merge_sort_before(first_list, second_list, s):
    """将两个列表是s1,s2按顺序融合为一个列表s,s为原列表"""
    # j和i就相当于两个指向的位置,i指s1,j指s2
    i, j = 0, 0
    while i+j < len(s):
        # j==len(s2)时说明s2走完了,或者s1没走完并且s1中该位置是最小的
        if j == len(second_list) or (i < len(first_list) and first_list[i] < second_list[j]):
            s[i+j] = first_list[i]
            i += 1
        else:
            s[i+j] = second_list[j]
            j += 1


def merge_sort(before_sort_list):
    """归并排序"""
    n = len(before_sort_list)
    # 剩一个或没有直接返回,不用排序
    if n < 2:
        return
    # 拆分
    mid = n // 2
    s1 = before_sort_list[0:mid]
    s2 = before_sort_list[mid:n]
    # 子序列递归调用排序
    merge_sort(s1)
    merge_sort(s2)
    # 合并
    merge_sort_before(s1, s2, before_sort_list)
    return before_sort_list

排序6— 快速排序

快速排序算是,最常用的排序算法了。大多数编程语言的类库也是基于快速排序为主开发的。

算法描述

  1. 快排首先会选择一个种子元素key,一般取序列的第一个元素为key。
  2. 然后从后往前把比key小的找出来,放在key前面,再从前往后找出比key大的,放在key的后面
  3. 直到所有子序列的长度不大于1,这样最终排序就完成了。

图形显示

在这里插入图片描述

代码实现

def fast_sort(sort_list, left, right):
    if left >= right:
        return sort_list
    key = sort_list[left]
    low = left
    high = right
    while left < right:
        while left < right and sort_list[right] > key:
            right -= 1
        sort_list[left] = sort_list[right]
        while left < right and sort_list[left] <= key:
            left += 1
        sort_list[right] = sort_list[left]
    sort_list[right] = key
    fast_sort(sort_list, low, left-1)
    fast_sort(sort_list, right+1, high)


def deal_sort_list(sort_list):
    length = len(sort_list)-1
    fast_sort(sort_list, 0, length)
    return sort_list

后记

本文的排序动态图片,来自于互联网,如有侵权,请联系注名原链接,或删除。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值