python 的 10个 经典算法

博主分享了在复习Python过程中的十大经典算法,代码附带详细注释,旨在帮助读者理解和学习。适合正在学习Python算法的开发者参考,后续还会持续更新。
部署运行你感兴趣的模型镜像
  • 最近在复习python呢,今年工作原因,工作换的厉害,大家是否也是一样呢。博主也是费劲脑汁····,欢迎互相讨论、学习!

不说了,上代码
代码有注释,方便复习和学习。喜欢的朋友留个关注哦。博主后续还会更新的。

numberList = [3, 10, 1, 55, 48, 18, 26, 34, 89, 55, 66, 77, 15, 29, 69, 1234]

'''
1. 冒泡排序
· 每两个相邻的元素进行比较,如果顺序不对,就进行更换,每次前后比较换一遍(从头到位比较一圈),最后的元素一定是最大的。
· 所以,每比较一遍,就要少进行比较一个元素(因为比较完一遍最后一个相对应的元素一定是最大的,以此类推···)。
'''


def bubbleSort(arr):
    lens = len(arr)
    for l in range(1, lens):
        for j in range(0, lens - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr


'''
2. 选择排序
· 每次遍历所有元素进行比较时,找到最小(大)元素,遍历完毕后将最小(大)的元素和未排序的第一个元素进行互换。
· 最后如果最小(大)元素没有变,将原地不动。
'''


def selectionSort(arr):
    lens = len(arr)
    for l in range(lens):
        minIndex = l
        for j in range(l + 1, lens):
            if arr[j] < arr[minIndex]:
                minIndex = j
        if l != minIndex:
            arr[l], arr[minIndex] = arr[minIndex], arr[l]
    return arr


'''
3. 插入排序
· 工作原理,通过有序序列,再对于无序序列元素,在已排序列中扫描,找到相应位置并插入  
· 获取列表长度,进行循环,获取当前元素current和上一个元素index。如果上一个元素大于(倒序是小于)当前元素,则将上一个元素向后移动一位,然后将当前元素移动到合适的位置,再将当前元素向后移动一位。
'''


def insertionSort(arr):
    for l in range(len(arr)):
        current = arr[l]
        index = l - 1
        while index >= 0 and arr[index] > current:
            arr[index + 1] = arr[index]
            index -= 1
        arr[index + 1] = current
    return arr


'''
4. 希尔排序
· 将一个原始序列,开分为多个子序列,将每一个子序列排序完毕,再合并为完全体
'''


def shellSort(arr):
    import math
    gap = 1
    length = len(arr)
    # 如果原始序列满足分块条件则进行分块
    while gap < (length / 3):
        gap = gap * 3 + 1
    # 如果gap 大于 0 每个子块就是还没有排序完毕,一直循环
    while gap > 0:
        # 子块进行排序
        for i in range(gap, length):
            temp = arr[i]
            j = i - gap
            # 如果元素 j 大于临时元素 temp,就进行元素互换
            while j >= 0 and arr[j] > temp:
                arr[j + gap] = arr[j]
                j -= gap
            arr[j + gap] = temp
        # 其中一个子块排序完毕,开始下一个子块
        gap = math.floor(gap / 3)
    return arr


'''
5.归并排序
· 将一个原始序列两两拆分,将拆分的两个序列传递到排序方法merge
· merge 将创建两个指针,对其两个指针进行比较,将小的元素放置到新序列中,直到取值完毕
'''


def mergeSort(arr):
    import math
    length = len(arr)
    # 如果序列长度小于2,则排序完毕,停止递归
    if length < 2:
        return arr
    # 创建一个相对应的列表切割数,再将其列表均分为两个,不断递归,直到原始列表被拆分完毕
    middle = math.floor(length / 2)
    left, right = arr[0:middle], arr[middle:]
    return merge(mergeSort(left), mergeSort(right))


def merge(left, right):
    # 将最小的元素暂存在一个新序列中
    result = []
    # 如果两个序列都有元素则不断循环,否则停止
    while left and right:
        # 比较两个两个列表指针,取其最小的一个元素添加到新序列中
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
    # 如果原始序列长度为基数,则将最后一个元素添加到新序列中
    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0))
    return result


'''
6. 快速排序
'''


def quickSort(arr, left=None, right=None):
    left = 0 if not isinstance(left, (int, float)) else left
    right = len(arr) - 1 if not isinstance(right, (int, float)) else right
    # 比较两基准值,如果比基准值小,排在前面,如果比基准值大则排在后面。
    if left < right:
        partitionIndex = partition(arr, left, right)
        quickSort(arr, left, partitionIndex - 1)
        quickSort(arr, partitionIndex + 1, right)
    return arr


def partition(arr, left, right):
    pivot = left
    index = pivot + 1
    i = index
    # 当该分区退出后,返回一个相对数列中间数,(分区数)
    while i <= right:
        if arr[i] < arr[pivot]:
            swap(arr, i, index)
            index += 1
        i += 1
    # 每次开始迭代之前不管条件成立与否都至少把一个元素(pivot)摆到当前分区最后的位置。
    swap(arr, pivot, index - 1)
    return index - 1


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


'''
7. 堆排序
· 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法用于升序排列
· 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法用于降序排列
'''

arrLen = 0


def buildMaxHeap(arr):
    import math
    for i in range(math.floor(len(arr) / 2), -1, -1):
        # 把堆首(最大值)和堆尾互换
        heapify(arr, i)


def heapify(arr, i):
    left = 2 * i + 1
    right = 2 * i + 2
    largest = i
    if left < arrLen and arr[left] > arr[largest]:
        largest = left
    if right < arrLen and arr[right] > arr[largest]:
        largest = right

    if largest != i:
        swaps(arr, i, largest)
        heapify(arr, largest)


def swaps(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]


def heapSort(arr):
    global arrLen
    arrLen = len(arr)
    # 创建一个堆
    buildMaxHeap(arr)
    for i in range(len(arr) - 1, 0, -1):
        swaps(arr, 0, i)
        # 把堆的尺寸缩小1,并调用heapify
        arrLen -= 1
        # 把新的数组顶端数据调整到相应位置
        heapify(arr, 0)
    return arr


'''
8. 计数排序
· 计数排序的核心在于将输入的数据值转化为键(maxValue)存在额外开辟的数组空间([0] * maxValue)。
· 作为一种线性时间复杂度的排序,技术排序要求输入的数据必须是有确定范围的整数。
'''


def countingSort(arr, maxValue):
    bucketLen = maxValue + 1
    # 开辟空间
    bucket = [0] * bucketLen
    sortedIndex = 0
    arrLength = len(arr)
    for i in range(arrLength):
        # 每次给输入的数据,在bucket 对应的 Index = 1
        bucket[arr[i]] += 1
    for j in range(bucketLen):
        # 如果 bucket[index]中的元素 大于0,则将 j(bucket的对应Index)赋值给要排序的数组,排序完毕为止。
        while bucket[j] > 0:
            arr[sortedIndex] = j
            sortedIndex += 1
            bucket[j] -= 1
    return arr


'''
9. 桶排序
类似于计数
· 开辟一个 arr中Max数 个桶。
· 取原始数组的每一个元素,对应到桶中的一个下标。如果有重复的,则往后添加。
'''


def bucketSort(arr):
    arrLens = len(arr)
    bucket = [0] * max(arr)
    for i in range(arrLens):
        bucket[arr[i] - 1] += 1
    res = []
    for i in range(len(bucket)):
        if bucket[i] != 0:
            res += [i + 1] * bucket[i]
    return res


'''
10. 基数排序
· 有运用到桶的机制,开辟一个额外空间,然后对号入桶。
· 有区别的是这个额外空间只有9个桶,因为不管多大的数字,它的个位数都对应0-9之间
· 排序max的位数次,不断针对对应的位数进行排,删,添
'''


def radixSorting(arr):
    import math
    i = 0
    j = len(str(max(arr)))
    # 排序最大“单位数”次
    while i < j:
        # 每一个单位数对应一个桶(max:9个)
        bucket_list = [[] for _ in range(10)]
        for x in arr:
            # 简单说是拿到桶的Index,其实是将arr中的元素单位从“个位”->“最大位数”的一个“单位数”。
            # 也就等于是Index(Index就是桶的位置),然后在对号入座。
            index = math.floor(x / (10 ** i)) % 10
            bucket_list[index].append(x)
        # 排序完一个单位后,清空原始列表,再进行下一个单位的排序。
        arr.clear()
        # 给原始列表添加每次变化后的元素
        [arr.append(y) for x in bucket_list for y in x]
        i += 1
    return arr


if __name__ == '__main__':
    print("冒泡排序:", bubbleSort(numberList))
    print("选择排序:", selectionSort(numberList))
    print("插入排序:", insertionSort(numberList))
    print("希尔排序:", shellSort(numberList))
    print("归并排序:", mergeSort(numberList))
    print("快速排序:", quickSort(numberList))
    print("堆排序:", heapSort(numberList))
    print("计数排序:", countingSort(numberList, max(numberList)))
    print("桶排序:", bucketSort(numberList))
    print("基数排序:", radixSorting(numberList))

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值