首页 > 编程知识 正文

Python之十大排序算法

时间:2023-11-20 02:49:02 阅读:294320 作者:WSIA

排序算法是计算机科学中的一个重要主题,它通过对一组元素进行排列,使其按照特定的顺序展示。Python作为一种功能强大且易于理解的编程语言,提供了多种排序算法的实现。本文将介绍Python中常用的十大排序算法,并且提供每个算法的代码示例。

一、冒泡排序

冒泡排序是一种简单的排序算法,它通过重复地交换相邻元素直到排序完成。该算法的时间复杂度为O(n^2)。

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

冒泡排序通过比较相邻的元素并交换它们的位置,将最大的元素逐渐“冒泡”到最后。这个过程像是气泡在水中逐渐上浮,因此得名冒泡排序。

二、选择排序

选择排序是一种简单直观的排序算法,它将待排序的序列分为已排序和未排序两部分,每次从未排序部分选择最小的元素放到已排序部分的末尾。该算法的时间复杂度也为O(n^2)。

def selection_sort(arr):
    n = len(arr)
    for i in range(n):
        min_idx = i
        for j in range(i+1, n):
            if arr[j] < arr[min_idx]:
                min_idx = j
        arr[i], arr[min_idx] = arr[min_idx], arr[i]
    return arr

选择排序每次从未排序的部分中选择最小的元素,然后将其与未排序部分的第一个元素交换位置。这样不断地选择最小的元素,直到整个序列有序。

三、插入排序

插入排序是一种简单、稳定且高效的排序算法,它将序列分为已排序和未排序两部分,每次从未排序部分选择一个元素插入已排序部分的合适位置。该算法的时间复杂度为O(n^2)。

def insertion_sort(arr):
    n = len(arr)
    for i in range(1, n):
        key = arr[i]
        j = i - 1
        while j >= 0 and arr[j] > key:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key
    return arr

插入排序类似于玩扑克牌时的整理牌堆操作,每次从未排序的部分选择一张牌插入已排序部分的合适位置。这个过程反复进行,直到整个序列有序。

四、希尔排序

希尔排序是一种基于插入排序的高效排序算法,它通过比较相隔一定步长的元素并交换它们的位置,逐渐缩小步长直到整个序列有序。该算法的时间复杂度为O(nlogn)。

def shell_sort(arr):
    n = len(arr)
    gap = n // 2
    while gap > 0:
        for i in range(gap, n):
            temp = arr[i]
            j = i
            while j >= gap and arr[j - gap] > temp:
                arr[j] = arr[j - gap]
                j -= gap
            arr[j] = temp
        gap //= 2
    return arr

希尔排序是插入排序的改进版,通过设置不同的步长来分组进行插入排序,逐渐减小步长直到为1。这样可以在保持插入排序简单性的同时,提高排序的效率。

五、归并排序

归并排序是一种高效稳定的排序算法,它采用分而治之的思想,将待排序序列分为若干子序列,分别进行排序后再合并。该算法的时间复杂度为O(nlogn)。

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = arr[:mid]
    right = arr[mid:]
    left = merge_sort(left)
    right = merge_sort(right)
    return merge(left, right)

def merge(left, right):
    result = []
    i = 0
    j = 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result.extend(left[i:])
    result.extend(right[j:])
    return result

归并排序将待排序序列分为若干子序列,递归地对子序列进行排序,然后再将排好序的子序列进行合并。这个过程类似于两个有序序列的合并操作。

六、快速排序

快速排序是一种高效的排序算法,它采用分而治之的思想和基准元素的策略,将待排序序列分为两个子序列,然后递归地对子序列进行排序。该算法的时间复杂度为O(nlogn)。

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[0]
    less = [x for x in arr[1:] if x <= pivot]
    greater = [x for x in arr[1:] if x > pivot]
    return quick_sort(less) + [pivot] + quick_sort(greater)

快速排序通过选择一个基准元素,将待排序序列分成两部分,使得左边的元素都小于基准元素,右边的元素都大于基准元素。然后递归地对两个子序列进行排序,最终将它们合并为有序的序列。

七、堆排序

堆排序是一种高效的排序算法,它利用堆这种数据结构进行排序。堆是一种完全二叉树,具有最大堆和最小堆两种形式。该算法的时间复杂度为O(nlogn)。

def heapify(arr, n, i):
    largest = i
    l = 2 * i + 1
    r = 2 * i + 2
    if l < n and arr[l] > arr[largest]:
        largest = l
    if r < n and arr[r] > arr[largest]:
        largest = r
    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)

def heap_sort(arr):
    n = len(arr)
    for i in range(n//2, -1, -1):
        heapify(arr, n, i)
    for i in range(n-1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)
    return arr

堆排序利用最大堆或最小堆的性质进行排序,在构建堆和调整堆的过程中完成排序操作。它通过不断地将最大(最小)元素与堆顶交换,并调整堆使其满足堆的性质。

八、计数排序

计数排序是一种基于计数的排序算法,它通过统计待排序序列中每个元素出现的次数,然后根据统计结果对元素进行排序。该算法的时间复杂度为O(n+k),其中k是序列中元素的取值范围。

def counting_sort(arr):
    n = len(arr)
    max_val = max(arr)
    count = [0] * (max_val+1)
    for i in range(n):
        count[arr[i]] += 1
    index = 0
    for i in range(max_val+1):
        for _ in range(count[i]):
            arr[index] = i
            index += 1
    return arr

计数排序通过统计每个元素的出现次数,然后根据统计结果构建有序序列。它适用于元素范围较小且重复值较多的情况。

九、桶排序

桶排序是一种基于映射的排序算法,它将待排序序列分组为若干个桶,并在每个桶内进行排序,然后按照桶的顺序依次输出。该算法的时间复杂度为O(n+k),其中k是桶的个数。

def bucket_sort(arr):
    min_val = min(arr)
    max_val = max(arr)
    bucket_size = (max_val - min_val) / len(arr)
    buckets = [[] for _ in range(len(arr))]
    for i in range(len(arr)):
        index = int((arr[i] - min_val) / bucket_size)
        buckets[index].append(arr[i])
    for i in range(len(arr)):
        buckets[i] = sorted(buckets[i])
    result = []
    for bucket in buckets:
        result.extend(bucket)
    return result

桶排序将待排序序列分为一定数量的桶,每个桶内进行排序,然后按照桶的顺序依次输出所有元素。它适用于元素分布均匀的情况。

十、基数排序

基数排序是一种基于数字位数的排序算法,它通过将待排序序列按照每个数字的位数进行排序,最终得到一个有序序列。该算法的时间复杂度为O(kn),其中k是数字的位数。

def radix_sort(arr):
    max_val = max(arr)
    exp = 1
    while max_val // exp > 0:
        counting_sort_by_digit(arr, exp)
        exp *= 10
    return arr

def counting_sort_by_digit(arr, exp):
    count = [0] * 10
    n = len(arr)
    result = [0] * n
    for i in range(n):
        index = arr[i] // exp
        count[index % 10] += 1
    for i in range(1, 10):
        count[i] += count[i - 1]
    i = n - 1
    while i >= 0:
        index = arr[i] // exp
        result[count[index % 10] - 1] = arr[i]
        count[index % 10] -= 1
        i -= 1
    for i in range(n):
        arr[i] = result[i]

基数排序按照数字的位数进行排序,先按照个位数排序,再按照十位数排序,依次进行直到最高位数。每一轮排序都利用计数排序的思想对数字进行排序。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。