六种排序算法及其复杂度(面试简答+python代码)

冒泡排序、插入排序、选择排序、快速排序、归并排序和堆排序的简要原理、时间复杂度、空间复杂度、优势和劣势:

排序算法原理时间复杂度空间复杂度优势劣势
冒泡排序通过比较相邻元素,将较大元素“冒泡”到右侧最好:O(n)
平均/最坏:O(n^2)
O(1)简单实现低效,对大数据集不适用
插入排序将元素插入已排序部分,保持有序性最好:O(n)
平均/最坏:O(n^2)
O(1)适用于部分已排序数据集对大数据集不够高效
选择排序选取最小元素放入已排序部分的末尾最好/平均/最坏:O(n^2)O(1)实现简单,不受输入分布影响性能相对较差
快速排序选取基准元素,分治递归和合并平均/最坏:O(n log n)
最好:O(n)
最坏:O(n)
平均:O(log n)
高效,适用于大数据集和小数据集最坏情况下性能退化,需要额外空间
归并排序分治递归和合并最好/平均/最坏:O(n log n)O(n)稳定的高效排序需要额外空间
堆排序构建最大堆,反复取出最大元素平均/最坏:O(n log n)O(1)原地排序,适用于大数据集实现相对复杂,不稳定,不适用于小数据集

一、冒泡排序(Bubble Sort)

1、简答

冒泡排序是一种简单的排序算法,它通过不断交换相邻元素的位置来将元素按照从小到大(或从大到小)的顺序排列。

时间复杂度为O(n^2),空间复杂度为O(1)。

冒泡排序是一种简单但低效的排序算法,在实际应用中并不是高效的排序算法,特别是对于大型数据集来说。

2、python代码

import random

# 生成随机数列表
num_list = [random.randint(1, 100) for _ in range(10)]

print("原始列表:", num_list)

# 冒泡排序
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]

bubble_sort(num_list)

print("排序后:", num_list)

输出

原始列表: [92, 79, 45, 60, 3, 41, 71, 45, 14, 61]
排序后: [3, 14, 41, 45, 45, 60, 61, 71, 79, 92]

二、选择排序(Selection Sort)

1、简答

选择排序是一种简单的排序算法,它通过不断选择未排序序列中最小(或最大)的元素来将元素按照从小到大(或从大到小)的顺序排列。

时间复杂度为O(n^2),空间复杂度为O(1)。

尽管选择排序不是最快的排序算法,但它的实现简单,在小型数据集上可能具有一定的优势,但效率较低,不适合大型数据集。

2、python代码

import random

# 生成随机数列表
num_list = [random.randint(1, 100) for _ in range(10)]

print("原始列表:", num_list)

# 选择排序
def selection_sort(arr):
    n = len(arr)
    for i in range(n):
        min_index = i
        for j in range(i+1, n):
            if arr[j] < arr[min_index]:
                min_index = j
        arr[i], arr[min_index] = arr[min_index], arr[i]

selection_sort(num_list)

print("排序后:", num_list)

输出:

原始列表: [34, 5, 11, 73, 31, 18, 98, 33, 47, 22]
排序后: [5, 11, 18, 22, 31, 33, 34, 47, 73, 98]

三、插入排序(Insertion Sort)

1、简答

插入排序是一种简单的排序算法,它通过不断将未排序元素插入已排序序列中来将元素按照从小到大(或从大到小)的顺序排列。
插入排序的主要思想是将数组分为已排序和未排序两部分。初始时,将第一个元素视为已排序,然后从未排序部分逐个选择元素,插入到已排序部分的适当位置,以保持已排序部分始终有序。

时间复杂度为O(n^2),空间复杂度为O(1)。

插入排序在处理小型数据集时可能比一些更复杂的算法更有效;具有稳定性;在某些情况下,插入排序在部分已排序的数据集上表现出色。

2、python代码

import random

# 生成随机数列表
num_list = [random.randint(1, 100) for _ in range(10)]

print("原始列表:", num_list)

# 插入排序
def insertion_sort(arr):
    n = len(arr)
    for i in range(1, n):
        key = arr[i]
        j = i - 1
        while j >= 0 and key < arr[j]:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key

insertion_sort(num_list)

print("排序后:", num_list)

输出:

原始列表: [22, 5, 25, 46, 41, 37, 66, 51, 22, 88]
排序后: [5, 22, 22, 25, 37, 41, 46, 51, 66, 88]

四、快速排序(Quick Sort)

1、简答

快速排序是一种常用的排序算法,它通过选取一个基准元素将数组分为两个子数组,然后递归对两个子数组进行排序来将元素按照从小到大(或从大到小)的顺序排列。
快速排序是一种高效的分治法排序算法,其主要思想是选择一个基准元素,将数组分成小于基准的左子数组和大于基准的右子数组,然后递归地对左右子数组进行排序,最终将它们合并起来。

时间复杂度为O(n log n)(平均情况,在最坏情况下可能达到O(n^2)),空间复杂度为O(log n)。

快速排序通常在实践中表现出色,特别是在处理大型数据集时。它是许多排序算法中速度最快的之一。

2、python代码

import random

# 生成随机数列表
num_list = [random.randint(1, 100) for _ in range(10)]

print("原始列表:", num_list)

# 快速排序
def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]  # 选择中间元素作为基准值
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

sorted_list = quick_sort(num_list)

print("排序后:", sorted_list)

输出:

原始列表: [96, 76, 6, 10, 21, 74, 46, 3, 47, 31]
排序后: [3, 6, 10, 21, 31, 46, 47, 74, 76, 96]

五、归并排序(Merge Sort)

1、简答

归并排序是一种稳定分治法排序算法,它通过将数组分为两个子数组,递归对两个子数组进行排序,然后将两个有序子数组归并为一个有序数组来将元素按照从小到大(或从大到小)的顺序排列。

时间复杂度为O(n log n),空间复杂度为O(n)。

归并排序的优点之一是它不受输入数据分布的影响,始终保持O(n log n)的时间复杂度,但其空间复杂度较高,需要额外的存储空间来保存临时数组。在处理大型数据集要求稳定排序的情况下,归并排序是一个很好的选择。

2、python代码

import random

# 生成随机数列表
num_list = [random.randint(1, 100) for _ in range(10)]

print("原始列表:", num_list)

# 归并排序
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    
    mid = len(arr) // 2
    left_half = arr[:mid]
    right_half = arr[mid:]
    
    left_half = merge_sort(left_half)
    right_half = merge_sort(right_half)
    
    return merge(left_half, right_half)

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

sorted_list = merge_sort(num_list)

print("排序后:", sorted_list)

输出:

原始列表: [24, 92, 90, 13, 78, 78, 100, 48, 96, 95]
排序后: [13, 24, 48, 78, 78, 90, 92, 95, 96, 100]

六、堆排序(Heap Sort)

1、简答

堆排序是一种常用的基于堆数据结构的排序算法,它通过将数组看作一个完全二叉树来进行排序,其主要思想是将待排序序列构建成一个最大堆,然后逐步将堆顶元素(最大元素)取出与最后一个元素交换并调整堆结构来将元素按照从小到大(或从大到小)的顺序排列。

时间复杂度为O(n log n),空间复杂度为O(1)。

与归并排序和快速排序不同,堆排序在实际实现中不需要额外的存储空间,因此它具有原地排序的特点。堆排序适用于大型数据集的情况,但相对于其他排序算法,它的实现可能稍显复杂

堆排序不是一个稳定的排序算法。在排序过程中,由于涉及到元素的交换,可能会导致相等元素的相对顺序发生变化,从而破坏稳定性。稳定性意味着在排序过程中,相等元素的相对顺序保持不变。

2、python代码

import random

# 生成随机数列表
num_list = [random.randint(1, 100) for _ in range(10)]

print("原始列表:", num_list)

# 堆排序
def heap_sort(arr):
    n = len(arr)
    
    # 构建最大堆
    for i in range(n // 2 - 1, -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)

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

heap_sort(num_list)

print("排序后:", num_list)

输出:

原始列表: [60, 34, 34, 74, 70, 32, 91, 82, 81, 42]
排序后: [32, 34, 34, 42, 60, 70, 74, 81, 82, 91]
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中常用的排序算法有冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序等。每个排序算法的时间复杂度不同。 冒泡排序的时间复杂度为O(n^2)。每次比较相邻的两个元素,如果顺序错误,则交换位置,重复这个过程直到整个数组排序完成。由于需要多次遍历数组,所以时间复杂度较高。 选择排序的时间复杂度也为O(n^2)。每次从未排序的部分中选择最小的元素,然后与未排序部分的第一个元素交换位置。重复这个过程直到整个数组排序完成。 插入排序的时间复杂度为O(n^2)。将未排序的元素逐个插入已排序的部分中的正确位置。具体操作是从后往前比较,如果当前元素比前一个元素小,则交换位置,重复这个过程直到整个数组排序完成。 快速排序的平均时间复杂度为O(nlogn)。通过选择一个基准元素,将数组分为两个子数组,其中一个子数组的所有元素小于基准元素,另一个子数组的所有元素大于基准元素。然后对两个子数组分别递归地进行快速排序,最后合并两个子数组得到有序数组。 归并排序的时间复杂度也为O(nlogn)。通过将数组递归地拆分成更小的子数组,然后对子数组进行排序,最后将排好序的子数组合并成一个有序数组。 堆排序的时间复杂度为O(nlogn)。首先将数组构建成一个最大堆或最小堆,然后不断地将堆顶元素与堆的最后一个元素交换位置,并重新调整堆,重复这个过程直到整个数组排序完成。 综上所述,Python中常用的排序算法及其时间复杂度如上所示。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [常见排序算法及其对应的时间复杂度和空间复杂度](https://blog.csdn.net/weixin_39734493/article/details/110335437)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [python实现排序算法 时间复杂度、稳定性分析 冒泡排序、选择排序、插入排序、希尔排序](https://blog.csdn.net/weixin_39852276/article/details/110335432)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值