python 实现几大排序算法

news/2024/5/19 5:10:43 标签: 算法, 排序算法, 快速排序, 数据结构, 堆排序

1、插入排序

插入排序的思想是由后往前插入,选择合适的位置插入之后,进行下一个操作。
稳定算法,时间复杂度O(n^2),空间复杂度O(1)。图源百度
插入排序

def insert_sort(nums):
    for i in range(len(nums)):
        tmp = nums[i]
        j = i
        # 如果当前位数字比前位数字小,将前位数字后移
        while j >=1 and nums[j-1] > tmp:
            nums[j] = nums[j-1]
            j -= 1
        # 此时j之前的位置都小于当前位数字,j之后的位置都大于当前位数字,将数字插入
        nums[j] = tmp
    return nums

2、希尔排序

希尔排序和插入排序相似,只不过是插入排序每次只迈一步,希尔排序每次迈一大步,然后步子变小,最后步子变成1。
不稳定算法,时间复杂度O(n^1.3-2),空间复杂度O(1)。图源百度
在这里插入图片描述

def shell_sort(nums):
    gap = len(nums)//2
    while gap>0:
        # 每次走一大步,进行插入排序
        for i in range(gap,len(nums)):
            tmp = nums[i]
            j = i
            while j >= gap and nums[j-gap] > tmp:
                nums[j] = nums[j-gap]
                j -= gap
            nums[j] = tmp
        # 步数变小,直至1
        gap = gap//2
    return nums

3、基数排序

基数排序是非比较的排序方法,先根据个位数插入到对应的桶中,再展开;然后根据十位数再插入到桶中,再展开;直到最高位。注意只能用于自然数的排序,毕竟有小数了,你没法插到桶里去啊!自己画一个图!
稳定排序,时间复杂度O((n+r)*k),空间复杂度O(r×n)。(n个数,r个桶,最大k位数)
在这里插入图片描述

def radix_sort(nums):
    max_len = len(str(max(nums)))
    for i in range(max_len):
        # 分配10个桶
        bucket_list = [[] for _ in range(10)]
        for j in nums:
            # 放到每个桶中
            bucket_list[j//(10**i)%10].append(j)
        # 展开
        nums = [q for p in bucket_list for q in p]
    return nums

4、冒泡排序

冒泡排序是每次找到最大(或最小)的数字,放在开头或者结尾。之所以叫冒泡的意思是泡泡是逐渐变大的过程。
稳定排序,时间复杂度O(n^2),空间复杂度O(1)

def bubble_sort(nums):
    for i in range(len(nums)):
        for j in range(1,len(nums)-i):
        	# 找到大的数字然后交换
            if nums[j] < nums[j-1]:
                nums[j],nums[j-1] = nums[j-1],nums[j]
    return nums

5、归并排序

归并排序是分治的思想,将序列拆成两份、四份、八份,,,最后直到长度为1的有序数列,然后再进行合并。
稳定排序,复杂度O(nlogn),空间复杂度O(n)。

def merge(nums,l,mid,r):
    # 分配空间
    tmp = [0]*(r-l+1)
    k = 0
    i = l
    j = mid+1
    # 合并两个有序数列
    while i<=mid and j<=r:
        if nums[i] < nums[j]:
            tmp[k] = nums[i]
            k += 1
            i += 1
        else:
            tmp[k] = nums[j]
            k += 1
            j += 1
    # 如果左边数列未合并完
    while i <= mid:
        tmp[k] = nums[i]
        k += 1
        i += 1
     # 如果右边数列未合并完
    while j <= r:
        tmp[k] = nums[j]
        k += 1
        j += 1
    nums[l:r+1] = tmp[:]
    return nums

def merge_sort(nums,l,r):
    if l < r:
        # 找到断开点
        mid = int(l+r)//2
        # 递归
        nums = merge_sort(nums,l,mid)
        nums = merge_sort(nums,mid+1,r)
        # 合并
        nums = merge(nums,l,mid,r)
    return nums

6、堆排序

堆排序是利用二叉树,将大的数字放在根结点(大顶堆),每次取出根结点之后重新调整堆,直至堆为空。
不稳定排序,时间复杂度O(nlogn),建堆时间O(n),空间复杂度O(1)

def heapify(nums,n,i):
    large = i
    l = 2 * i + 1 # 左节点
    r = 2 * i + 2 # 右节点
    if l < n and nums[large] < nums[l]: # 往左节点走
        large = l
    if r < n and nums[large] < nums[r]: # 往右节点走
        large = r
    if large != i:
        # 调整根结点和子节点的大小
        nums[i],nums[large] = nums[large],nums[i]
        # 当跟节点的值变化时,调整改变节点的堆(不一定是大顶堆)
        heapify(nums,n,large)
def heap_sort(nums):
    n = len(nums)
    for i in range(n,-1,-1):
        # n是长度,i是节点序号,保证每一个节点都是大顶堆
        heapify(nums,n,i)
    # 最大数在根结点
    for i in range(n-1,-1,-1):
        # 取出根结点之后放在最后的位置,将最后位置值调到根结点
        nums[i],nums[0] = nums[0],nums[i]
        # 调整堆
        heapify(nums,i,0)
    return nums

7、桶排序

桶排序就是将数据划分成几个大小区间,然后再进行排序,可以同其它排序想结合。
稳定性取决于桶内算法的稳定性,空间复杂度和时间复杂度同样受桶内排序算法的影响。

def bucket_sort(nums):
    max_num = nums[0]
    min_num = nums[0]
    for i in nums:
        if max_num < i:
            max_num = i
        if min_num > i:
            min_num = i
    # 根据最大值、最小值划分桶的个数
    bucket_num = int((max_num - min_num)/len(nums)) + 1
    bucket = [ [] for _ in range(bucket_num)]
    for i in range(len(nums)):
        bucket[int((nums[i] - min_num)/len(nums))].append(nums[i])
    # 在每个桶内进行排序
    for i in range(bucket_num):
        # 偷懒,直接sort排序
        bucket[i].sort()
    k = 0
    for i in range(bucket_num):
        for val in bucket[i]:
            nums[k] = val
            k += 1
    return nums

8、快速排序

快排是思路是将小于当前位的数字放在左边,大于当前位的数字放在右边,是比较算法里面最高效的算法
不稳定、时间复杂度O(nlogn),空间复杂度O(1)。图源百度
在这里插入图片描述

def quick_sort(nums,left,right):
    if left >= right:
        return nums
    # 取左边作为当前位的值
    tmp = nums[left]
    i = left
    j = right
    while i!=j:
        # 如果右边的值比当前位大,右指针左移
        while i<j and nums[j] >= tmp:
            j -= 1
        # 当右边的值比当前位小的时候,交换值
        nums[i],nums[j] = nums[j],nums[i]
        # 如果左边的值比当前位小,左指针右移
        while i<j and nums[i] <= tmp:
            i += 1
        # 当左边的值比当前位大的时候,交换值
        nums[i],nums[j] = nums[j],nums[i]
    # 对左、右边进行排序
    nums = quick_sort(nums,i+1,right)
    nums = quick_sort(nums,left,i-1)
    return nums

好了全部写完了,小伙伴们要记得动手哦!


http://www.niftyadmin.cn/n/819206.html

相关文章

基于深度学习的目标检测综述(单阶段、多阶段、FPN变体、旋转目标检测等)

随着深度学习的发展&#xff0c;基于深度学习的目标检测方法因其优异的性能已经得到广泛的使用。目前经典的目标检测方法主要包括单阶段(YOLO、SSD、RetinaNet&#xff0c;还有基于关键点的检测方法等)和多阶段方法(Fast RCNN、Faster RCNN、Cascade RCNN等&#xff09;。下面主…

详解经典旋转目标检测算法RoI Transformer

一、引言 1、旋转目标检测检测 旋转目标检测检测就是将具有旋转方向的目标检测出来&#xff0c;也就是需要检测目标的中心点、长宽、角度。在俯视图的目标检测中比较常见&#xff0c;如遥感图像目标检测、航拍图像目标检测等。(见下图旋转目标检测&#xff0c;图源论文RoI Tr…

python中值滤波、最大池化、平均池化、canny边缘检测(石原里美系列一)

一、常见三种滤波器介绍 中值滤波&#xff1a;取卷积区域内的中位数 最大池化&#xff1a;取卷积区域内的最大值 平均池化&#xff1a;取卷积区域内的均值 边缘检测&#xff1a;边缘检测就是找到图像的边缘信息(轮廓) 二、故事背景 有一天&#xff0c;石原里美小姐姐出去玩&…

Tesla Open AI Day解读

一、前言 2021年08月20日&#xff0c;特斯拉在Open AI Day上介绍了最新的自动驾驶进展。视频YouTube链接、B站链接。智能驾驶三要素&#xff1a;安全、舒适、高效。整个介绍主要分为三个部分&#xff0c;第一部分视觉感知&#xff0c;主要是通过视觉方法实现检测、识别、分割、…

计算机视觉中的经典骨干网络总结

特征提取是计算机视觉任务的基础&#xff0c;良好的特征提取网络可以明显的提升算法的性能表现。在计算机视觉任务中&#xff0c;对图像进行特征提取的网络被称作为骨干网络&#xff08;Backbone&#xff09;&#xff0c;可以说是下游任务的主心骨了。下面总结近年来研究者们提…

我有7个女朋友,真是个大渣男!

本篇漫画故事改编自知乎高赞回答作者&#xff1a;文歆云链接&#xff1a;https://www.zhihu.com/question/295467353/answer/495676981漫画原创公众号&#xff1a;不会笑青年&#xff0c;授权转载请联系微信(laughyouth369)&#xff0c;授权后&#xff0c;请在原创发表48小时后…

有钱任性,马斯克变推特最大股东!然而,特斯拉发布重大消息…

推荐阅读&#xff1a;《这波裁员着实厉害&#xff01;》《别被带坏了。。。》1投票成股东&#xff1f;有钱就是任性&#xff0c;一夜之间世界首富就成了推特的最大股东&#xff0c;最近推特的股价也是一路狂飙。这个炒股技术&#xff0c;天下无敌了。那怎么世界首富突然就想收购…

Linux实操(一):vi和vim的使用

一、vi和vim的基本介绍 所有的Linux 系统都会内建vi文本编辑器。 Vim具有程序编辑的能力&#xff0c;可以看做是Vi的增强版本&#xff0c;可以主动的以字体颜色辨别语法的正确性&#xff0c;方便程序设计。代码补完、编译及错误跳转等方便编程的功能特别丰富&#xff0c;在程序…