几种典型排序算法及其python实现(一)

本文详细介绍了四种常见排序算法:冒泡排序的稳定性和O(n²)时间复杂度,快速排序的不稳定性和平均O(nlogn)效率,插入排序的稳定性和O(n²)特点,以及希尔排序的改进插入排序性质和O(nlogn)~O(n²)时间范围。通过Python代码演示和分析,对比了这些算法在实际应用中的优劣。
摘要由CSDN通过智能技术生成

本文排序算法分析和代码参考:https://www.bilibili.com/video/BV1Aq4y1S7nb?p=11&spm_id_from=pageDriver

0. 排序算法的分类

  1. 比较类算法:通过比较来确定元素间的先后顺序,时间复杂度不能突破O(nlogn),非线性时间比较类排序
  2. 非比较类的时间复杂度:使用空间换取时间
  • 算法稳定性, a=b,且a在b前面,排序之后a是否仍然在b的前面
  • 时间复杂度
  • 空间复杂度

1. 冒泡排序

1.1 算法思路

  1. 外层循环每一次都对相邻的元素进行排序,将小的元素放到上面(或者),内层循环遍历到倒数第二个;
  2. 重复进行排序;

1.2 Python实现

python代码:

def bubbleSort(nums):
    # 外层遍历,记录遍历次数
    for i in range(len(nums)):
        # 内层遍历,每层遍历len(nums)-1-i次即可
        for j in range(len(nums) - 1 - i):
            # 如果下一个元素等于当前元素,交换两个位置
            if nums[j] > nums[j + 1]:
                nums[j], nums[j + 1] = nums[j + 1], nums[j]
    return nums


nums = [2, 3, 8, 4, 2, 0, 7, 8]
print(bubbleSort(nums))

1.3 分析

排序算法的稳定性:排序前后,数值相同的两个元素相对位置不发生变化,稳定的
时间复杂度:O(N2)

2. 快速排序

2.1 算法思路

算法流程:

  1. 先从数列中选择一个数作为基准
  2. 将比这个数大的全部放在右边,小的有放在左边
  3. 对左右区间重复第二步,直到各个区间只有一个数

一次分区过程:

  1. 设置两个变量,i=0,j=N-1
  2. 以第一个数为基准数,赋值给pivot,即pivot=A[0]=A[i]
  3. j从后往前搜索(j–),找到第一个小于pivot的值A[j],将A[j]和A[i]交换,更新基准pivot
  4. i从前向后搜索(i++),找到第一个大于pivot的值A[i],更新A[j]和A[i]交换
  5. 重复3,4直到i==j

一次快排之后原本的数组被分成两部分,左边的都小于基准,右边的都大于基准。然后在左

边和右边分别进行排序;

引用自身考虑使用递归算法:

2.2 Python实现

def quickSort(nums, low, hight):
    # 设置头尾指针,i和j
    i, j = low, hight
    while i < j:
        # 设置当前基准为nums[i]
        pivot = nums[i]
        # 从后往前遍历,如果nums[j]>=pivot,则继续遍历,直到小于基准
        while i < j and nums[j] >= pivot:
            j -= 1
        # 交换此时的i和j对应元素并更新基准为nums[j]
        nums[j], nums[i] = nums[i], nums[j]
        pivot = nums[j]
        # 从前向后遍历,如果nums[i]<=pivot,则继续遍历,直到大于基准
        while i < j and nums[i] <= pivot:
            i += 1
        # 交换此时的i和j对应元素并更新基准为nums[i]
        nums[j], nums[i] = nums[i], nums[j]
        # 进行递归,对基准值左边,右边元素分别递归;
        quickSort(nums, low, j - 1)
        quickSort(nums, j + 1, hight)
    return nums

nums = [0, 2, -2, -3, 3]
print(quickSort(nums, 0, len(nums) - 1))

2.3 分析

稳定性:不稳定,相同元素排序之后相对位置可能发生变化;

时间复杂度: 递归的,每次排序时间复杂度是O(N)的,排序次数是二分的O(logN),因此,快速排序的总体时间复杂度是O(NlogN),最坏的情况变成O(N2)。

3. 插入排序

3.1 算法思路

把n个待排序的元素看成一个有序表,一个无序表。开始时有序表中只有一个元素,无序表中间有n-1个元素,排序是每次从无序表中间取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表。重复n-1次可以完成排序。

3.2 Python实现

def insertSort(nums):
    # 外层循环,遍历nums
    for i in range(0, len(nums) - 1):
        j = i+1
        # 从i开始遍历后面的无序列表,并从后向前插入到有序列表中
        while len(nums) > j >= 1:
            # 当前元素小于前一个元素则交换两个元素
            if nums[j] < nums[j - 1]:
                nums[j], nums[j - 1] = nums[j - 1], nums[j]
            j -= 1

    return nums


nums = [-5, -2, -4, 6, 1, 1, 3]
print(insertSort(nums))

3.3 分析

稳定性:稳定的

时间复杂度:O(N2),外层循环n-1次,每一次排序次数和n相关

4. 希尔排序

4.1 算法思路

简单插入排序的改良版本

简单排序的方法:如果数据最小值在在后面,其排序的时间会变得比较长

按照下标进行分组,对于每组进行直接的插入算法排序,随着增量逐渐减少,每组元素越来越多,当增量为1时,整个元素分成一组,算法终止;

4.2 python实现

 def shellSort(nums):
    l = len(nums)
    # 初始增量设置为len(nums)//2
    gap = l // 2
    # 外层对增量进行循环
    while gap >= 1:
        # 第二层从索引为gap开始往后遍历nums
        for i in range(gap, len(nums)):
            # 第三层从索引为i,往前遍历,每次向前移动gap
            for j in range(i, -1, -gap):
                # 如果num[j]<nums[j-gap],交换两个元素
                if j >= gap and nums[j] < nums[j - gap]:
                    nums[j], nums[j - gap] = nums[j - gap], nums[j]
        # 更新gap
        gap = gap // 2
    return nums


nums = [1, 2, 4, 1, 1, 2, -1, 0, 2, 5]
print(shellSort(nums))

4.3 分析

稳定性:不稳定,是一种插入排序

时间复杂度:O(nlogn)~O(n2),两者之间

和顺序有关,和递归方式有关

5. 选择排序

5.1 算法分析

首先在没有排序的序列中找到最小元素,放在起始位置。然后,从剩余没有排序的元素中继续寻找最小元素,放到已经排序的序列末尾。直到所有元素排序完成。如图所示:
引用自最上面的连接

5.2 Python实现

def selectSort(nums):
    # 外层循环遍nums,到len(nums)-1即可
    for i in range(len(nums) - 1):
        # 内层循环从i+1开始
        for j in range(i + 1, len(nums)):
            # 设置初始最小值的索引为i
            min_index = i
            # 如果nums[j]>nums[i],将min_index替换为j
            if nums[i] > nums[j]:
                min_index = j
            # 一轮循环完成之后,将nums[i]和索引值最小对应的值交换
            nums[i], nums[min_index] = nums[min_index], nums[i]

    return nums


nums = [-1, 2, 1, 0, -1, -2]
print(selectSort(nums))

5.3 分析

稳定性:不稳定

时间复杂度O(N2)

以上是五种排序算法的思路及其python实现代码。这几种算法都是比较类排序算法,后续会介绍堆排序,归并排序,以及计数排序,桶排序(其中后面两个是非比较的排序方法);
see you~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值