刷题系列——排序算法

news2024/11/18 3:35:57

参考:README - 十大经典排序算法

1)排序算法分为内部外部排序两种,这个之前并不了解,外部排序需要访问外存的这个就是指需要额外内存比如另一个list或者dict存储中间结果。

2)稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同,这点之前也不了解。

1. 冒泡排序:每次比较两个元素,随着遍历数组,最小的元素会浮到数组顶端。

        1. 做完第一次遍历,最大的元素会到数组末端;每一次保证一个元素到了正确的位置,因此之后的遍历会逐渐缩短长度。

        2. 实现: j和i的边界可以注意一下,当前是优化的写法。

def bubble_sort(lista):
    num = len(lista)
    for j in range(1, num):
        for i in range(num - j):
            if lista[i] > lista[i + 1]:
                lista[i], lista[i + 1] = lista[i + 1], lista[i]
    print(lista)
    return lista

lista = [1,5,6,3,7,9,1]
bubble_sort(lista)

        3. 复杂度:最小O(n)是已经正序,最大O(n^2)是倒序,平均O(n^2),空间复杂度O(1),稳定,In-place。

2. 选择排序:每次遍历选择出最大/小元素放在尾/首,下一次选择次之。

        1. 需要记录最大/小元素的索引,涉及到交换最大/小元素和首/尾元素。

        2. 实现        

def select_sort(lista):
    num = len(lista)
    for i in range(num - 1):
        min_ele = i
        for j in range(i + 1, num):
            if lista[j] < lista[min_ele]:
                min_ele = j
        lista[i], lista[min_ele] = lista[min_ele], lista[i]
    print(lista)
    return lista

        3. 复杂度:最小O(n^2),最大O(n^2),平均O(n^2),空间复杂度O(1),不稳定,In-place。

        4. 不稳定这个点需要注意,涉及到交换位置,所以相同大小元素本来的顺序会被打乱。

3. 插入排序:类比扑克牌

        1. 保证一个已排列数组,插入的数据从后扫描已排列数组然后插入。

        2. 把一个数组划分已排列和未排列待插入部分。

        3. 实现:注意j的变化, j -= 1

def insert_sort(lista):
    num = len(lista)
    for i in range(1, num):
        j = i
        while j - 1 >= 0 and lista[j] < lista[j - 1]:
            lista[j - 1], lista[j] = lista[j], lista[j - 1]
            j -= 1
                
    print(lista)

        4. 最小O(n),最大O(n^2),平均O(n^2),空间复杂度O(1),稳定,In-place。

4. 希尔排序:递减增量排序算法

        1. 对插入排序的优化:将待排序部分划分为子序列,各自基本有序后,之后再插入排序。包含有归并的思路。

        2. 子序列的划分方式是很重要的,如果连续几个数划分为一个子序列,对整体效率是无影响的,因此需要采用增量划分。

        3. 增量是指划分的子序列的个数,增量递减直到为1,排序结束。

​​​​​​​

        3. 不稳定因为子序列的排序会打乱原顺序。

        4. 实现

def shell_sort(lista):
    num = len(lista)
    increment = num // 2
    while increment > 0:
        for i in range(increment, num):
            idx = i
            while idx >= increment and  lista[idx] < lista[idx - increment]:
                lista[idx], lista[idx - increment] = lista[idx - increment], lista[idx]
                idx -= increment
        increment //= 2
    print(lista)

        5. 最小O(nlgn),其他不太确定,空间复杂度O(1),不稳定因为包含了插入排序,In-place。

5. 归并排序:分治法,需要额外空间

        1. 分为自上而下的递归和自下而上的迭代,这点还不是很理解。

        2. 参考:【Python入门算法23】排序入门:高效的归并排序 mergesort 的4种写法 - 知乎

        3. 实现

    
def merge_sort(lista):
    if len(lista) == 1:
        return lista
    idx = len(lista) // 2
    left = merge_sort(lista[:idx])
    right = merge_sort(lista[idx:])
    merged = merge_1(left, right)
    print(merged)
    return merged

def merge(lista, listb):
    merged = []
    a, b = len(lista), len(listb)
    i, j = 0, 0
    while i < a and j < b:
        if lista[i] < listb[j]:
            merged.append(lista[i])
            i += 1
        else:
            merged.append(listb[j])
            j += 1
    merged.extend(lista[i:])
    merged.extend(listb[j:])
    return merged

def merge_1(lista, listb):
    if not lista:
        return listb
    if not listb:
        return lista
    
    if lista[0] < listb[0]:
        return [lista[0]] + merge_1(lista[1:], listb)
    else:
        return [listb[0]] + merge_1(lista, listb[1:])

6. 快速排序:采用分治法

        1. 找到基准,基准左边比基准小,右边比基准大。

        2. 对冒泡排序的改进,是内部排序的最优。

        3. 实现 

def quick_sort(lista, start, end):
    if start >= end:
        return lista[start:end]
    pivot = lista[start]
    left = start
    right = end
    while left < right:
        while lista[right] >= pivot and left < right:
            right -= 1
        while lista[left] < pivot and left < right:
            left += 1
        lista[left], lista[right] = lista[right], lista[left]
    lista[left] = pivot
        
    quick_sort(lista, start, left-1)
    quick_sort(lista, left+1, end)
    print(lista)

7. 堆排序:利用堆的数据结构,大顶堆用于升序排序和小顶堆用于降序排序

        1. 构建堆,交换堆元素,重新构建堆

        2. 参考:​​​​​​​Python实现堆排序_堆排序python-CSDN博客

        3. 实现 

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

def heapify(lista, start, end):
    root = start
    left = root * 2 + 1
    while left <= end:
        if left + 1 <= end and lista[left] < lista[left + 1]:
            left += 1
        if lista[root] < lista[left]:
            lista[root], lista[left] = lista[left], lista[root]
            root = left
            left = root * 2 + 1
        else:
            break 

        4. 平均复杂度Ο(nlogn),不稳定。

8. 计数排序:需要额外空间

        1. 将输入的值转化为key存储在额外的空间中

        2. 实现

def counting_sort(lista):
    n = len(lista)
    min_v = 222222222
    max_v = 0
    for ele in lista:
        if ele > max_v:
            max_v = ele
        if ele < min_v:
            min_v = ele
    num = max_v - min_v + 1
    listb = [0] * num
    for i in lista:
        listb[i - min_v] += 1
    idx = 0
    for i in range(max_v - min_v + 1):
        for j in range(listb[i]):
            lista[idx] = i + min_v
            idx += 1
    print(lista)
    return lista

        3. 平均复杂度Ο(n+k),这个k的部分暂时不是很理解,空间复杂度O(k)。Out-place,不稳定。

9. 桶排序:计数排序的升级版

        1. 包括分桶和合并两部分,对桶内的数据进行排序,再把桶内排序好的数据取出,又称为箱排序

        2. 实现:里面调用了冒泡排序,调用快排时发现上面的代码有问题

def bucket_sort(lista):
    listb = []
    min_value = 222222222222
    max_value = 0
    for i in lista:
        if i > max_value:
            max_value = i
        if i < min_value:
            min_value = i
    bucket_num = (max_value - min_value) // 3 + 1
    buckets = [[] for i in range(bucket_num)]
    for i in lista:
        buckets[(i - min_value) // 3].append(i)
    print(buckets)
    for b in buckets:
        b = bubble_sort(b)
        print(b)
        listb.extend(b)
    print(listb)

        3. 是否稳定决定于桶内的排序算法。最快情况是数据被桶平分(n/k),具体复杂度决定于桶内的排序算法。

10. 基数排序:非比较型的排序算法,和桶排序思想类似

        1. 除了对整数排序,也可以用于浮点数,字符串等。

        2. 按位数分桶,分为MSD,LSD两种方法。

        3. 实现

def radix_sort(lista):
    max_value = max(lista)
    place = 0
    while max_value >= 10 ** (place):
        place += 1
    buckets = [[] for i in range(10)]
    for i in range(place):
        for j in lista:
            ele = j % (10 ** (i + 1))
            buckets[ele].append(j)
        k = 0
        for bucket in buckets:
            if bucket:
                lista[k] = bucket.pop(0)
                k += 1
    print(lista)

        4. 时间复杂度O(d(n+k)),d是最大值的位数,k是桶个数,n是队列长度。稳定,Out-place。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1283493.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#基础与进阶扩展合集-进阶篇(持续更新)

目录 本文分两篇&#xff0c;基础篇点击&#xff1a;C#基础与进阶扩展合集-基础篇 一、进阶 1、Predicate 2、设置C#语言版本 3、ListCollectionView过滤集合 4、值类型与引用类型 5、程序设置当前项目工作目录 6、获取App.config配置文件中的值 7、Linq常用语句 8、…

三种定时器的实现方式

一、Scheduled Schedule是Spring框架提供的一种简单的定时任务调度方法&#xff0c;通过注解的方式即可实现定时任务的调度。它适用于简单的定时任务需求&#xff0c;例如每隔一段时间执行一次任务或者在特定时间执行任务。Scheduled可以轻松地集成到Spring应用中&#xff0c;…

DeepVoice AI - Text To Voice

No sign-up, No API Keys, no recurr

LabVIEW开发工业设备远程在线状态监测

LabVIEW开发工业设备远程在线状态监测 项目需要减少意外停机和维护费用、提供更完整的机器操作和状态图、改进设备使用情况跟踪。 该解决方案是一个多节点&#xff08;即多站点&#xff09;远程监控系统&#xff0c;它利用了基于NI cRIO的控制器和定制的LabVIEW监测软件。 方…

Idea 导入Mysql8.0驱动jar包

库是模块可以依赖的已编译代码的集合。在IntelliJ IDEA中&#xff0c;可以在三个级别上定义库&#xff1a; 全局 &#xff08;可用于许多项目&#xff09;&#xff0c; 项目&#xff08;可用于项目中的所有模块&#xff09;和模块 &#xff08;可用于一个模块&#xff09; 简单…

Leetcode 80 删除排序数组中的重复项 II

class Solution {// 双指针// slow代表已完成需要的数组的后一位&#xff0c;即要插入的位置// fast代表待检查的第一个元素public int removeDuplicates(int[] nums) {return f(nums, 2);}public int f(int[] nums, int k){int n nums.length;int slow k;int fast k;while(…

开源CDN软件GoEdge —— 筑梦之路

官方网站&#xff1a;GoEdge CDN - 制作自己的CDN - GoEdge CDN | 自建CDN GoEdge是一款管理分布式CDN边缘节点的开源工具软件&#xff0c;目的是让用户轻松地、低成本地创建CDN/WAF等应用。 特性 免费 - 开源、免费、自由、开放 简单 - 架构简单清晰&#xff0c;安装简单&a…

vue2使用ElementUI

elementui官网&#xff1a;组件 | Element 1、全部引入 下载&#xff1a;npm i element-ui 在 main.js 中写入以下内容&#xff1a;import Vue from vue; import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import App from ./App.vue;Vue.use(…

12月2号作业

#include <iostream>using namespace std; class Sofa{ private:string setting;string *lying new string;public:Sofa(){cout << "Sofa::无参构造函数" << endl;}Sofa(string setting,string lying):setting(setting),lying(new string (lying)…

封装带插槽的表格

子组件 <template><div><table><thead><tr><th v-for"col,colIndex in columns" :key"colIndex">{{ col.title }}</th></tr></thead><tbody v-if"instList.length >0"><tr …

IDEA 保存自动ESLint格式化

作为后端人员&#xff0c;偶尔修改一下前端代码&#xff0c;ESLint总提示格式不正确。有没有什么办法实现自动格式化呢&#xff1f; 安装插件Save Actions Tool 设置中搜索eslint 勾选 Run eslint --fix on save 这样以后&#xff0c;只要保存文件就会自动格式化了。 参考 …

Python 流程控制

目录 程序流程 顺序结构 分支结构 单分支 双分支 多分支 if 嵌套 循环结构 while循环 for 循环 退出循环 循环与分支嵌套 附录 程序流程 程序是由语句构成&#xff0c;而流程控制语句 是用来控制程序中每条语句执行顺序的语句。可以通过控制语句实现更丰富的逻辑…

vue+electron问题汇总

1. Vue_Bug Failed to fetch extension, trying 4 more times 描述&#xff1a;项目启动时报错 解决&#xff1a;注释图片中内容 2. Module not found: Error: Can’t resolve ‘fs’ in 描述&#xff1a;项目启动报错 解决&#xff1a;vue.config.js中添加图中数据 3.导入…

开会做笔记的时候用什么软件比较好?

在工作生涯中&#xff0c;会经历很多大大小小的会议&#xff0c;而如何快速准确记录下会议上重要的内容&#xff0c;成了很多上班族的必修课。在会上做笔记&#xff0c;选择什么样的工具才能事半功倍&#xff0c;成了一个值得深思的问题。而经过一段时间的测评后&#xff0c;我…

Windows系统下配置多个版本的jdk

1:准备多个版本的jdk 下载地址:Java Downloads | Oracle 2:安装多个版本的jdk 3:跳转到环境变量配置页 主要是配置环境变量,win10系统操作如下 1)搜索控制面板 2)点击系统与安全 3)点击系统 4)点击高级系统设置 5)点击环境变量 4:为多个版本的jdk配置环境变量 将多个版本的jd…

深度学习(五):pytorch迁移学习之resnet50

1.迁移学习 迁移学习是一种机器学习方法&#xff0c;它通过将已经在一个任务上学习到的知识应用到另一个相关任务上&#xff0c;来改善模型的性能。迁移学习可以解决数据不足或标注困难的问题&#xff0c;同时可以加快模型的训练速度。 迁移学习的核心思想是将源领域的知识迁…

专业做除甲醛净化器的品牌 甲醛净化器什么牌子最好用

室内产生了超标的甲醛&#xff0c;大部分都会采取选择甲醛空气净化器来去除&#xff0c;甲醛净化器逐渐成为室内清除甲醛的主力&#xff0c;在选择甲醛净化器时&#xff0c;人们常常会被市场上琳琅满目的空气净化器品牌所迷惑&#xff0c;各品牌和型号都声称自己最好&#xff0…

关于 Windows 11 显示更多选项

更新 Windows 11 后&#xff0c;右键鼠标出现 显示更多选项&#xff0c;本文解决如何默认显示所有选项 默认显示更多选项 winR打开运行框输入cmd回车输入下面的命令并回车&#xff0c;重启系统 reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c9…

10、SQL注入——数据库基础

文章目录 一、数据库概述二、数据库分类Mysql数据库连接方法 三、识别数据库四、SQL语法4.1 SQL基本语法4.2 高级操作 一、数据库概述 数据库&#xff08;database&#xff09;&#xff1a;存储在磁盘、磁带、光盘或其他外存介质上、按一定结构组织在一起的相关数据的集合。数…

Linux常用命令——atq命令

在线Linux命令查询工具 atq 列出当前用户的at任务列表 补充说明 atq命令显示系统中待执行的任务列表&#xff0c;也就是列出当前用户的at任务列表。 语法 atq(选项)选项 -V&#xff1a;显示版本号&#xff1b; -q&#xff1a;查询指定队列的任务。实例 at now 10 minu…