刷LeetCode:冒泡排序详解 【2/1000 第二题】含imagemagick动态效果图

news2024/11/25 11:34:11

👤作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。
会一些的技术:数据分析、算法、SQL、大数据相关、python
作者专栏每日更新:
LeetCode解锁1000题: 打怪升级之旅

LeetCode解锁1000题: 打怪升级之旅https://blog.csdn.net/cciehl/category_12625714.html
python数据分析可视化:企业实战案例https://blog.csdn.net/cciehl/category_12615648.html
备注说明:方便大家阅读,欢迎关注公众号 数据分析螺丝钉  回复关键词 【学习资料】领取notebook和代码调试过程,一起打怪升级

今日推荐:imagemagick 是一个功能强大的图像处理工具,本文用来记录每个运行的步骤通过GIF来呈现

 

题目描述

​输入:[74,55,35,79,57,71,81,5,82,1]

输出:[1,5,35,55,57,71,74,79,81,82]

冒泡算法

冒泡排序是计算机科学中最简单的排序算法之一。这个算法的名字来源于较小的元素会通过交换逐渐“冒泡”到列表的顶端,就像水中的气泡一样。

算法原理

冒泡排序算法的核心原理基于两个嵌套循环,通过反复交换数组中相邻的元素,直到整个数组排序完成。其主要过程分为两部分:

  1. 内循环(比较与交换):算法从数组的第一个元素开始,比较相邻的元素对 (j, j+1)。如果 j 位置的元素大于 j+1 位置的元素(对于升序排序),则这两个元素的位置会被交换。这一过程一直重复,直到到达数组的末尾。每完成一轮内循环,都能保证这一轮中最大的元素被"冒泡"到其最终位置(即数组的最右端)。

    1. 要注意的优化:防止已经排序的重复执行,通过增加一个标志位 flag ,若在某轮「内循环」中未执行任何交换操作,则说明数组已经完成排序,直接返回结果即可。这个在已经排序好的情况下 可以减少不必要的比较

  2. 外循环(迭代排序的过程):外循环控制内循环的重复执行,每执行完一次内循环后,排序的范围就减少一个元素(因为每次内循环都会将当前未排序部分的最大元素放到正确的位置)。外循环持续进行,直到整个数组排序完成。

让我们一起如图跟着一起过一遍

 

7fce2b2ccb50e7b241c9ff5b3afd52fd.png

方便大家理解 这里调用 imagemagick 记录每一次的排序图片生成GIF动态演示每个冒泡的步骤

 

b2372abc5d03cef4cf7cc7d98f258489.gif

冒泡算法

def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        swapped = False  # 初始化标志位
        for j in range(1, n - i):
            steps += 1  # Increment steps for each comparison
            if arr[j - 1] > arr[j]:
                arr[j], arr[j - 1] = arr[j - 1], arr[j]  # Swap the elements
                swapped = True
        if not swapped:
            break

算法复杂度

时间复杂度:平均和最坏情况下是O(n^2),最佳情况是O(n)(如果列表已经排序)

空间复杂度:O(1),因为它是一个原地排序算法

完整代码

有使用动态效果图展示,所以需要先安装 imagemagick,安装步骤简介

Windows:

  1. 访问 ImageMagick 的官方下载页面: ImageMagick Download
  2. 下载适用于 Windows 的安装程序。
  3. 运行安装程序并遵循提示进行安装。在安装过程中,确保选中“Add application directory to your system path”以便在任何命令行窗口中使用 ImageMagick。

macOS:

可以使用 Homebrew 安装 ImageMagick:

  1. 打开终端。
  2. 如果您还没有安装 Homebrew,请先安装它。可以从 Homebrew 官网 获取安装命令。
  3. 安装 ImageMagick,运行以下命令:
brew install imagemagick
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
​
def bubble_sort(arr):
    """
    Performs bubble sort on a list and counts the steps.
​
    Parameters:
    arr (list): The list to be sorted.
​
    Returns:
    (list, int): A tuple of the sorted list and the number of steps taken.
    """
    n = len(arr)
    steps = 0  # Initialize step count
    for i in range(n):
        swapped = False
        for j in range(1, n - i):
            steps += 1  # Increment steps for each comparison
            if arr[j - 1] > arr[j]:
                arr[j], arr[j - 1] = arr[j - 1], arr[j]  # Swap the elements
                swapped = True
        if not swapped:
            break
    return arr, steps
​
def bubble_sort_unoptimized(arr):
    n = len(arr)
    steps = 0  # Initialize step count
    for i in range(n): # 外循环
        for j in range(0, n-i-1): # 内循环
            steps += 1
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr,steps
​
def initialize_animation(arr):
    """
    Initializes the bar chart and text annotations for the animation.
​
    Parameters:
    arr (list): The list based on which bars are plotted.
​
    Returns:
    tuple: Contains the figure, axis, bars, and text annotations.
    """
    fig, ax = plt.subplots()
    bar_rects = ax.bar(range(len(arr)), arr, color='skyblue')
    ax.set_ylim(0, int(max(arr) * 1.1))
    text_annotations = [ax.text(rect.get_x() + rect.get_width() / 2, rect.get_height(), str(val), ha='center', va='bottom') 
                        for rect, val in zip(bar_rects, arr)]
    steps_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)
    return fig, ax, bar_rects, text_annotations, steps_text
​
def update_animation(frame, arr, bar_rects, text_annotations, steps_text, steps_count):
    """
    Update function for the animation that shows the sorting process.
​
    Parameters:
    frame (int): The current frame number in the animation.
    arr (list): The list being sorted.
    bar_rects (BarContainer): The bars representing the list elements.
    text_annotations (list of Text): The text annotations for each bar.
    steps_text (Text): The text annotation for the number of steps.
    steps_count (list of int): A list containing a single integer that counts the steps.
    """
    n = len(arr)
    swapped = False
    for i in range(n - 1):
        if arr[i] > arr[i + 1]:
            arr[i], arr[i + 1] = arr[i + 1], arr[i]  # Swap elements
            swapped = True
            steps_count[0] += 1  # Increment the steps count
            break
    # Update the bars and text annotations
    for rect, val, text in zip(bar_rects, arr, text_annotations):
        rect.set_height(val)
        text.set_text(str(val))
        text.set_position((rect.get_x() + rect.get_width() / 2, val))
    steps_text.set_text(f'Steps: {steps_count[0]}')  # Update the steps display
    if not swapped:
        anim.event_source.stop()  # Stop the animation if no swaps occurred
​
# Main execution part
if __name__ == "__main__":
    # Define the unsorted array
    unsorted_arr = [74, 55, 35, 79, 57, 71, 81, 5, 82, 1]
    # Perform bubble sort and get the sorted array with step count
    sorted_arr, steps = bubble_sort(unsorted_arr.copy())
    print(f'Sorted array: {sorted_arr}')
    print(f'Steps taken: {steps}')
​
    # Initialize the animation plot
    fig, ax, bar_rects, text_annotations, steps_text = initialize_animation(unsorted_arr)
​
    # Create the animation object
    anim = FuncAnimation(fig, update_animation, fargs=(unsorted_arr, bar_rects, text_annotations, steps_text, [0]),
                         frames=range(len(unsorted_arr)**2), interval=500, repeat=False)
​
    # Save the animation to a GIF file
    anim.save('bubble_sort_with_steps.gif', writer='pillow', fps=2)

 

 

 

 

 

 

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

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

相关文章

鸿蒙OS开发实例:【ArkTS类库多线程I/O密集型任务开发】

使用异步并发可以解决单次I/O任务阻塞的问题,但是如果遇到I/O密集型任务,同样会阻塞线程中其它任务的执行,这时需要使用多线程并发能力来进行解决。 I/O密集型任务的性能重点通常不在于CPU的处理能力,而在于I/O操作的速度和效率。…

代码随想录第25天 | 组合总和||| 、 电话号码的字母组合

一、前言 参考文献:代码随想录 今天的还是回溯算法,主要用到了昨天的回溯组合方法和巧妙思路方法,让我们继续为算法打基础吧! 二、组合总和||| 1、思路: 这一题和昨日的组合没啥太大区别只是遍历的范围变为了固定…

2024 年高效开发的 React 生态系统

要使用 React 制作应用程序,需要熟悉正确的库来添加您需要的功能。例如,要添加某个功能(例如身份验证或样式),您需要找到一个好的第三方库来处理它。 在这份综合指南中,我将向您展示我建议您在 2024 年使用…

VS2019连接MySQL

VS2019连接MySQL 下载MySQL Connector/C配置头文件,库文件路径配置头文件路径配置库的路径复制dll文件 MySQL的用户设置将权限赋值给新用户 编写代码往数据库写入 老师布置的作业让我们用VS2019连接MySQL实现一个小型的日志系统,中间踩了很多的坑&#x…

神经网络与深度学习(一)误差反传BP算法

误差反传BP算法 1多层感知机1.1XOR问题1.2多层感知机 2.BP算法2.1简述2.2详解2.2.1输入输出模型2.2.2梯度下降算法迭代2.2.3前向传播在输出端计算误差2.2.4误差反传--输出层2.2.5误差反传--隐含层2.2.6误差反传--总结 1多层感知机 1.1XOR问题 线性不可分问题: 无法…

C++心决之命名空间、重载函数和引用

目录 1. C关键字(C98) 2. 命名空间 2.1 命名空间定义 2.2 命名空间使用 3. C输入&输出 4. 缺省参数 4.1 缺省参数概念 4.2 缺省参数分类 5. 函数重载 5.1 函数重载概念 5.2 C支持函数重载的原理--名字修饰(name Mangling) 6. 引用 6.1 引用概念 6.2 引用特性…

Java多线程:定位死锁

检测死锁可以使用jconsole工具,或使用jps定位进程id,再用jstack定位死锁 方案1: 1. 先用jps查看所有的java进程id 2. jstack 进程id定位死锁 3. 查看死锁结果 方案2:从jdk的安装路径中找到bin目录, 点击jconsole

Linux线程原理以及基础操控函数使用(1)

线程原理 这一个课程的笔记 LWP:light weight process 轻量级的进程,本质仍是进程(在Linux环境下) 进程:独立地址空间,拥有PCB 线程:有独立的PCB,但没有独立的地址空间(共享) 区别:在于是否共…

算法6.4-6.6DFS

一个不知名大学生,江湖人称菜狗 original author: Jacky Li Email : 3435673055qq.com Time of completion:2024.03.27 Last edited: 2024.03.27 目录 算法6.4-6.6DFS 第1关:算法6.5采用邻接矩阵表示图的深搜 任务描述 相关知识 编程要求…

数据结构——优先级队列及多服务台模拟系统的实现

一、优先级队列的定义和存储 优先级队列定义:优先级高的元素在队头,优先级低的元素在队尾 基于普通线性表实现优先级队列,入队和出队中必有一个时间复杂度O(n),基于二叉树结构实现优先级队列,能够让入队和出队时间复杂度都为O(log…

RabbitMQ--04--发布订阅模式 (fanout)-案例

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 发布订阅模式 (fanout)---案例前言RabbitListener和RabbitHandler的使用 1.通过Spring官网快速创建一个RabbitMQ的生产者项目2.导入项目后在application.yml文件中配…

Python编程-并发编程基础梳理与高级特性案例讲解

Python编程-并发编程基础梳理与高级特性案例讲解 同步、异步通信与IO阻塞 同步(Synchronous)和异步(Asynchronous)通信是两种不同的通信方式,涉及到处理任务的时序和相互等待的关系。同步通信简单直观,但可…

Unity 使用TrailRenderer制作拖尾效果

使用TrailRenderer实现拖尾效果,具体操作步骤如下: 1、创建一个空对象 在Unity场景中创建一个空对象 2、添加TrailRenderer组件 选择步骤1创建的空对象,然后在Inspector面板中点击“Add Component”按钮,搜索并添加TrailRende…

蓝桥杯第七届大学B组详解

目录 1.煤球数量; 2.生日蜡烛; 3.凑算式 4.方格填数 5.四平方和 6.交换瓶子 7.最大比例 1.煤球数量 题目解析:可以根据题目的意思,找到规律。 1 *- 1个 2 *** 3个 3 ****** 6个 4 ********** 10个 不难发现 第…

C++入门知识详细讲解

C入门知识详细讲解 1. C简介1.1 什么是C1.2 C的发展史1.3. C的重要性1.3.1 语言的使用广泛度1.3.2 在工作领域 2. C基本语法知识2.1. C关键字(C98)2.2. 命名空间2.2 命名空间使用2.2 命名空间使用 2.3. C输入&输出2.4. 缺省参数2.4.1 缺省参数概念2.4.2 缺省参数分类 2.5. …

Linux - 第三节

改变用户类型 su 仅单纯的进行身份变化 依旧处于普通用户里面 su - 进行重新登录更改身份 退出用exit / ctrld su 用户名 改成成其他身份 对一条命令进行提权 sudo command r:可读 w:可写 x:可执行 -:对应的权限位置,没有权限 去掉所有权限 chmod u…

Qt中继承QCheckBox的类结合QTableWidget实现多选并且每个多选的id都不一样

1.相关描述 继承QCheckBox的类MyCheckBox&#xff0c;利用QTableWidget的setCellWidget方式添加MyCheckBox类的对象 2.相关页面 3.相关代码 mycheckbox.h #ifndef MYCHECKBOX_H #define MYCHECKBOX_H#include <QCheckBox> #include <QObject>class MyCheckBox : pu…

Elvis Presley 英文阅读

Elvis Presley 官方翻译 One of the most popular American singers of thetwentieth century was Elvis Presley. He made theRock & Roll music popular around the world. He sold millions of records and made manysuccessful films, and he helped change the dir…

基于SSM医院病历管理系统

基于SSM医院病历管理系统的设计与实现 摘要 病历管理系统是医院管理系统的重要组成,在计算机技术快速发展之前&#xff0c;病人或者医生如果想记录并查看自己的健康信息是非常麻烦的&#xff0c;因为在以往病人的健康信息通常只保存在自己的病历卡或者就诊报告中&#xff0c;…

TikTok直播专线:解决出海网络问题痛点,提升商业效率

近年来&#xff0c;TikTok作为全球最受欢迎的社交媒体平台之一&#xff0c;成为商家获取商机与市场的重要平台。然而&#xff0c;尽管商家纷纷进入TikTok&#xff0c;试图借助其强大的社交网络进行产品推广和销售&#xff0c;但在TikTok平台进行直播时&#xff0c;往往会遇到网…