算法基础:五大排序算法Python实战教程

排序是每个算法工程师和开发者都需要一些知识的技能。 不仅要通过编码实现,还要对编程本身有一般性的了解。 不同的排序算法是算法设计如何在程序复杂性,速度和效率方面具有如此强大影响的完美展示。
让我们来看看前6种排序算法,看看我们如何在Python中实现它们!
一、冒泡排序

冒泡排序是数据分析中常用的算法,因为它清楚地演示了排序的工作原理,同时简单易懂。 冒泡排序逐步遍历列表并比较相邻的元素对。 如果元素的顺序错误,则会交换元素。 重复遍历列表的未排序部分,直到列表被排序。 因为冒泡排序重复通过列表中未排序的部分,所以它具有最差的O(n2)复杂度。

def bubble_sort(arr):
    def swap(i, j):
        arr[i], arr[j] = arr[j], arr[i]

    n = len(arr)
    swapped = True

    x = -1
    while swapped:
        swapped = False
        x = x + 1
        for i in range(1, n-x):
            if arr[i - 1] > arr[i]:
                swap(i - 1, i)
                swapped = True

return arr

二、选择排序
选择排序也很简单,但通常优于冒泡排序。如果您在两者之间进行选择,最好默认选择排序。 使用Selection排序,我们将输入列表/数组分为两部分:已排序的项目子列表和剩余要排序的项目子列表构成列表的其余部分。 我们首先找到未排序子列表中的最小元素,并将其放在已排序子列表的末尾。 因此我们不断抓取最小的未排序元素,并将其按排序子列表中的排序顺序放置。 该过程以迭代方式继续,直到列表完全排序。

def selection_sort(arr):        
    for i in range(len(arr)):
        minimum = i

        for j in range(i + 1, len(arr)):
            # Select the smallest value
            if arr[j] < arr[minimum]:
                minimum = j

        # Place it at the front of the 
        # sorted end of the array
        arr[minimum], arr[i] = arr[i], arr[minimum]

return arr

三、插入排序

与冒泡排序和选择排序相比,插入排序更快且可以说更简单。 有趣的是这是有多少人在玩纸牌游戏时对卡片进行排序! 在每次循环迭代中,插入排序从数组中删除一个元素。 然后它会在另一个已排序的数组中找到该元素所属的位置,并将其插入其中。 它重复此过程,直到没有输入元素。

def insertion_sort(arr, simulation=False):

    for i in range(len(arr)):
        cursor = arr[i]
        pos = i

        while pos > 0 and arr[pos - 1] > cursor:
            # Swap the number down the list
            arr[pos] = arr[pos - 1]
            pos = pos - 1
        # Break and do the final swap
        arr[pos] = cursor

return arr

四、合并排序
合并排序是Divide and Conquer算法的完美典范。 它简单地使用了这种算法的2个主要步骤:
(1)连续划分未排序列表,直到有N个子列表,其中每个子列表有1个“未排序”元素,N是原始数组中元素的数量。
(2)反复合并,即一次比较2个子列表,以产生新的排序子列表,直到所有元素完全合并为单个排序数组。

 

def merge_sort(arr):
    # The last array split
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    # Perform merge_sort recursively on both halves
    left, right = merge_sort(arr[:mid]), merge_sort(arr[mid:])

    # Merge each side together
    return merge(left, right, arr.copy())


def merge(left, right, merged):

    left_cursor, right_cursor = 0, 0
    while left_cursor < len(left) and right_cursor < len(right):

        # Sort each one and place into the result
        if left[left_cursor] <= right[right_cursor]:
            merged[left_cursor+right_cursor]=left[left_cursor]
            left_cursor += 1
        else:
            merged[left_cursor + right_cursor] = right[right_cursor]
            right_cursor += 1

    for left_cursor in range(left_cursor, len(left)):
        merged[left_cursor + right_cursor] = left[left_cursor]

    for right_cursor in range(right_cursor, len(right)):
        merged[left_cursor + right_cursor] = right[right_cursor]

return merged

五、快速排序
快速排序也是一种分而治之的算法。 虽然它有点复杂,但在大多数标准实现中,它的执行速度明显快于合并排序,很少达到O(n²)的最坏情况复杂度。 它有3个主要步骤:
(1)我们首先从数组中选择一个数据作为基准数。
(2)将小于基准数的所有元素移动到基准数的左侧; 将所有大于基准数的元素移动到基准数的右侧。 这称为分区操作。
(3)递归地将上述两个步骤分别应用于每个元素子阵列,直到其值小于和大于最后一个基准数。

 

def partition(array, begin, end):
    pivot_idx = begin
    for i in xrange(begin+1, end+1):
        if array[i] <= array[begin]:
            pivot_idx += 1
            array[i], array[pivot_idx] = array[pivot_idx], array[i]
    array[pivot_idx], array[begin] = array[begin], array[pivot_idx]
    return pivot_idx

def quick_sort_recursion(array, begin, end):
    if begin >= end:
        return
    pivot_idx = partition(array, begin, end)
    quick_sort_recursion(array, begin, pivot_idx-1)
    quick_sort_recursion(array, pivot_idx+1, end)

def quick_sort(array, begin=0, end=None):
    if end is None:
        end = len(array) - 1

return quick_sort_recursion(array, begin, end)

 

微信公众号:python练手项目实战
更多机器学习算法的学习欢迎关注我的个人公众号,里面有更多机器学习与深度学习的文章,希望能和更多学习机器学习的伙伴相互交流和成长。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值