Python十大排序方式(详解+示例+查询链接)

Python十大排序方式(详解+示例+查询链接)

文章目录

  • Python十大排序方式(详解+示例+查询链接)
    • 1 冒泡排序(Bubble Sort):
    • 2 选择排序(Selection Sort):
    • 3 插入排序(Insertion Sort):
    • 4 堆排序(Heap Sort):
    • 5 归并排序(Merge Sort):
    • 6 快速排序(Quick Sort):
    • 7 希尔排序(Shell Sort):
    • 8 计数排序(Counting Sort):
    • 9 桶排序(Bucket Sort):
    • 10 基数排序(Radix Sort):
    • 11 更多

1 冒泡排序(Bubble Sort):

  • 基本思想:重复地遍历数组,比较相邻的两个元素,如果它们的顺序错误就交换它们,直到数组完全有序。
  • 时间复杂度:最好情况是O(n),当数组已经有序时;最坏情况是O(n2),当数组逆序时;平均情况是O(n2)。
  • 空间复杂度:O(1),只需要常数个额外空间。
  • 稳定性:稳定的排序算法,保持相等元素的相对顺序。
  • 代码示例:
def bubble_sort(array):
    n = len(array)
    for i in range(n - 1):
        swapped = False # 标记是否发生了交换
        for j in range(n - 1 - i):
            if array[j] > array[j + 1]: # 如果相邻元素顺序错误,就交换它们
                array[j], array[j + 1] = array[j + 1], array[j]
                swapped = True
        if not swapped: # 如果没有发生交换,说明数组已经有序,提前结束循环
            break
    return array

2 选择排序(Selection Sort):

  • 基本思想:在未排序的数组中找到最小(或最大)的元素,将它放到数组的起始位置,然后重复这个过程,直到数组完全有序。
  • 时间复杂度:最好情况,最坏情况,平均情况都是O(n^2)。
  • 空间复杂度:O(1),只需要常数个额外空间。
  • 稳定性:不稳定的排序算法,可能改变相等元素的相对顺序。
  • 代码示例:
def selection_sort(array):
    n = len(array)
    for i in range(n - 1):
        min_index = i # 记录最小元素的索引
        for j in range(i + 1, n):
            if array[j] < array[min_index]: # 如果找到更小的元素,更新最小元素的索引
                min_index = j
        if min_index != i: # 如果最小元素不在起始位置,就交换它们
            array[i], array[min_index] = array[min_index], array[i]
    return array

3 插入排序(Insertion Sort):

  • 基本思想:将数组分为已排序和未排序的两部分,每次从未排序的部分取出一个元素,插入到已排序的部分的合适位置,直到数组完全有序。
  • 时间复杂度:最好情况是O(n),当数组已经有序时;最坏情况是O(n2),当数组逆序时;平均情况是O(n2)。
  • 空间复杂度:O(1),只需要常数个额外空间。
  • 稳定性:稳定的排序算法,保持相等元素的相对顺序。
  • 代码示例:
def insertion_sort(array):
    n = len(array)
    for i in range(1, n):
        key = array[i] # 取出未排序部分的第一个元素
        j = i - 1 # 已排序部分的最后一个元素的索引
        while j >= 0 and array[j] > key: # 从后往前遍历已排序部分,找到合适的插入位置
            array[j + 1] = array[j] # 将大于key的元素后移一位
            j -= 1
        array[j + 1] = key # 将key插入到正确的位置
    return array

4 堆排序(Heap Sort):

  • 基本思想:利用堆这种数据结构的性质,将数组构建成一个大顶堆(或小顶堆),然后将堆顶元素与堆尾元素交换,缩小堆的范围,再调整堆,重复这个过程,直到堆的大小为1,此时数组完全有序。
  • 时间复杂度:最好情况,最坏情况,平均情况都是O(nlogn)。
  • 空间复杂度:O(1),只需要常数个额外空间。
  • 稳定性:不稳定的排序算法,可能改变相等元素的相对顺序。
  • 代码示例:
def heap_sort(array):
    n = len(array)
    # 构建大顶堆
    for i in range(n // 2 - 1, -1, -1): # 从最后一个非叶子节点开始,自下而上,自右而左调整堆
        heapify(array, n, i)
    # 排序
    for i in range(n - 1, 0, -1): # 从堆尾到堆顶,依次将堆顶元素与堆尾元素交换,然后调整堆
        array[0], array[i] = array[i], array[0]
        heapify(array, i, 0) # 调整堆的大小为i,堆顶索引为0
    return array

def heapify(array, n, i): # 调整堆的大小为n,堆顶索引为i
    largest = i # 记录最大元素的索引
    left = 2 * i + 1 # 左孩子的索引
    right = 2 * i + 2 # 右孩子的索引
    if left < n and array[left] > array[largest]: # 如果左孩子大于父节点,更新最大元素的索引
        largest = left
    if right < n and array[right] > array[largest]: # 如果右孩子大于父节点,更新最大元素的索引
        largest = right
    if largest != i: # 如果最大元素不是父节点,就交换它们,并递归地调整子树
        array[i], array[largest] = array[largest], array[i]
        heapify(array, n, largest)

5 归并排序(Merge Sort):

  • 基本思想:利用分治的思想,将数组分为两个子数组,分别对它们进行排序,然后将两个有序的子数组合并成一个有序的数组,重复这个过程,直到数组的大小为1,此时数组完全有序。
  • 时间复杂度:最好情况,最坏情况,平均情况都是O(nlogn)。
  • 空间复杂度:O(n),需要一个与原数组大小相同的辅助数组。
  • 稳定性:稳定的排序算法,保持相等元素的相对顺序。
  • 代码示例:
def merge_sort(array):
    n = len(array)
    if n <= 1: # 如果数组大小为1,直接返回
        return array
    mid = n // 2 # 找到数组的中点
    left = merge_sort(array[:mid]) # 对左半部分进行排序
    right = merge_sort(array[mid:]) # 对右半部分进行排序
    return merge(left, right) # 合并两个有序的子数组

def merge(left, right): # 合并两个有序的子数组
    i = 0 # 左数组的索引
    j = 0 # 右数组的索引
    k = 0 # 辅助数组的索引
    n1 = len(left) # 左数组的大小
    n2 = len(right) # 右数组的大小
    temp = [0] * (n1 + n2) # 辅助数组,大小为两个

6 快速排序(Quick Sort):

  • 基本思想:利用分治的思想,选择一个基准元素(pivot),将数组分为两个子数组,使得左边的子数组中的元素都小于等于基准元素,右边的子数组中的元素都大于等于基准元素,然后对两个子数组递归地进行快速排序,直到数组的大小为1或0,此时数组完全有序。
  • 时间复杂度:最好情况是O(nlogn),当每次选择的基准元素能够平均划分数组时;最坏情况是O(n^2),当每次选择的基准元素是数组的最大或最小元素时;平均情况是O(nlogn)。
  • 空间复杂度:O(logn),需要栈空间来存储递归调用的信息。
  • 稳定性:不稳定的排序算法,可能改变相等元素的相对顺序。
  • 代码示例:
def quick_sort(array, left, right):
    if left < right: # 如果数组有至少两个元素
        pivot = partition(array, left, right) # 对数组进行划分,返回基准元素的索引
        quick_sort(array, left, pivot - 1) # 对左子数组进行快速排序
        quick_sort(array, pivot + 1, right) # 对右子数组进行快速排序
    return array

def partition(array, left, right):
    pivot = array[right] # 选择最右边的元素作为基准元素
    i = left # i指向左子数组的末尾
    for j in range(left, right): # 遍历除了基准元素以外的元素
        if array[j] <= pivot: # 如果当前元素小于等于基准元素
            array[i], array[j] = array[j], array[i] # 将当前元素交换到左子数组的末尾
            i += 1 # 左子数组的长度加一
    array[i], array[right] = array[right], array[i] # 将基准元素交换到左子数组的右边
    return i # 返回基准元素的索引

7 希尔排序(Shell Sort):

  • 基本思想:基于插入排序的思想,将数组分为若干个子序列,每个子序列的元素相隔一定的间隔(称为增量),对每个子序列进行插入排序,然后逐渐减小增量,重复这个过程,直到增量为1,此时数组完全有序。
  • 时间复杂度:取决于增量的选择,最好情况是O(n),当数组已经有序时;最坏情况是O(n2),当增量为1时;平均情况是O(n1.3)。
  • 空间复杂度:O(1),只需要常数个额外空间。
  • 稳定性:不稳定的排序算法,可能改变相等元素的相对顺序。
  • 代码示例:
def shell_sort(array):
    n = len(array)
    gap = n // 2 # 初始增量为数组长度的一半
    while gap > 0: # 当增量大于0时
        for i in range(gap, n): # 对每个子序列进行插入排序
            key = array[i] # 取出未排序部分的第一个元素
            j = i - gap # 已排序部分的最后一个元素的索引
            while j >= 0 and array[j] > key: # 从后往前遍历已排序部分,找到合适的插入位置
                array[j + gap] = array[j] # 将大于key的元素后移gap位
                j -= gap
            array[j + gap] = key # 将key插入到正确的位置
        gap //= 2 # 减小增量
    return array

8 计数排序(Counting Sort):

  • 基本思想:假设数组中的元素都是在一个范围内的整数,创建一个与该范围大小相同的辅助数组,统计每个元素出现的次数,然后根据辅助数组中的信息,将元素放到正确的位置,使得数组有序。
  • 时间复杂度:O(n+k),其中n是数组的大小,k是数组中元素的范围。
  • 空间复杂度:O(n+k),需要一个与原数组大小相同的输出数组,和一个与元素范围大小相同的辅助数组。
  • 稳定性:稳定的排序算法,保持相等元素的相对顺序。
  • 代码示例:
def counting_sort(array, max_val):
    n = len(array)
    output = [0] * n # 输出数组,与原数组大小相同
    count = [0] * (max_val + 1) # 计数数组,大小为最大值加一,对应0-max_val的数值
    for x in array: # 遍历原数组,统计每个数值的出现次数
        count[x] += 1
    for i in range(1, max_val + 1): # 计算每个数值在输出数组中的结束位置
        count[i] += count[i - 1]
    for x in reversed(array): # 从后往前遍历原数组,将元素放入输出数组的正确位置
        output[count[x] - 1] = x # 将元素放入输出数组的对应位置
        count[x] -= 1 # 更新计数数组
    for i in range(n): # 将输出数组复制到原数组
        array[i] = output[i]

9 桶排序(Bucket Sort):

  • 基本思想:假设数组中的元素都是在一个范围内的实数,将该范围划分为若干个相同大小的子区间,称为桶,创建一个与桶的数量相同的辅助数组,每个桶对应一个链表,遍历原数组,将每个元素放入对应的桶中,然后对每个桶中的元素进行排序,最后将所有桶中的元素依次放回原数组,使得数组有序。
  • 时间复杂度:O(n+k),其中n是数组的大小,k是桶的数量。如果使用了较好的排序算法对每个桶进行排序,那么一般情况下,桶排序的时间复杂度接近于O(n)。
  • 空间复杂度:O(n+k),需要一个与原数组大小相同的输出数组,和一个与桶的数量相同的辅助数组。
  • 稳定性:稳定的排序算法,保持相等元素的相对顺序。
  • 代码示例:
def bucket_sort(array):
    n = len(array)
    max_val = max(array) # 数组中的最大值
    min_val = min(array) # 数组中的最小值
    bucket_range = (max_val - min_val) / n # 每个桶的范围
    bucket_list = [[] for _ in range(n + 1)] # 辅助数组,每个桶是一个链表
    for x in array: # 遍历原数组,将每个元素放入对应的桶中
        bucket_list[int((x - min_val) // bucket_range)].append(x)
    i = 0 # 原数组的索引
    for bucket in bucket_list: # 遍历辅助数组,对每个桶中的元素进行排序
        bucket.sort() # 这里可以

10 基数排序(Radix Sort):

  • 基本思想:利用分治的思想,将数组中的元素按照每一位的数值分配到不同的桶中,然后按照桶的顺序收集元素,重复这个过程,直到所有的位都被处理过,此时数组完全有序。
  • 时间复杂度:O(d*(n+k)),其中d是数组中元素的最大位数,n是数组的大小,k是桶的数量。
  • 空间复杂度:O(n+k),需要一个与原数组大小相同的输出数组,和一个与桶的数量相同的辅助数组。
  • 稳定性:稳定的排序算法,保持相等元素的相对顺序。
  • 代码示例:
def radix_sort(array):
    max_val = max(array) # 数组中的最大值
    exp = 1 # 当前处理的位数,从个位开始
    while max_val // exp > 0: # 当还有位数未处理时
        counting_sort(array, exp) # 对当前位数进行计数排序
        exp *= 10 # 处理下一位数

def counting_sort(array, exp): # 根据指定的位数进行计数排序
    n = len(array)
    output = [0] * n # 输出数组,与原数组大小相同
    count = [0] * 10 # 计数数组,大小为10,对应0-9的数值
    for x in array: # 遍历原数组,统计每个数值在当前位数上的出现次数
        index = (x // exp) % 10 # 计算当前位数上的数值
        count[index] += 1
    for i in range(1, 10): # 计算每个数值在输出数组中的结束位置
        count[i] += count[i - 1]
    for x in reversed(array): # 从后往前遍历原数组,将元素放入输出数组的正确位置
        index = (x // exp) % 10 # 计算当前位数上的数值
        output[count[index] - 1] = x # 将元素放入输出数组的对应位置
        count[index] -= 1 # 更新计数数组
    for i in range(n): # 将输出数组复制到原数组
        array[i] = output[i]

11 更多

如果您想了解更多关于排序算法的信息,您可以访问以下链接:

  • Radix Sort (With Code in Python, C++, Java and C) - Programiz
  • Python Program for Radix Sort - GeeksforGeeks
  • Radix Sort in Python - Stack Abuse
  • sorting - Radix sort python grammar - Stack Overflow
  • Python Sorting Algorithm: Radix Sort - Python in Plain English
  • 31
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值