只会用 Go 写 O(N²) 的冒泡排序算法?来看看优化后最好情况下的 O(N) 算法吧

news2024/12/26 23:37:44

只会用 Go 写 O N² 的冒泡排序算法?来看看优化后最好情况下的 O N 算法吧

  • 冒泡排序
  • 图片演示
  • 普通的冒泡排序算法
  • 优化算法
  • 小结

耐心和持久胜过激烈和狂热。

哈喽大家好,我是陈明勇,今天分享的内容是使用 Go 实现冒泡排序算法。如果本文对你有帮助,不妨点个赞,如果你是 Go 语言初学者,不妨点个关注,一起成长一起进步,如果本文有错误的地方,欢迎指出!

冒泡排序

冒泡排序是交换排序中最简单的一种算法。
算法思路:

  • 遍历数组,相邻的两个元素进行比较,以升序为例,如果前面的元素大于后面的元素,则将它们的位置进行交换
  • 第一轮遍历结束之后,最大的元素会处于所遍历范围的最后一个位置,然后继续下一轮遍历
  • 每轮都会固定一个元素,直到所有元素都被固定,因此会执行 n - 1轮,n 为元素的个数,也就是数组(切片)的长度。为什么会是 n - 1 而不是 n,因为到了第 n 轮,只剩下最后一个元素没有被固定,没有元素可以和它进行比较了,因此第 n 轮可以忽略。

图片演示

冒泡排序演示

  • 第一轮遍历 [4, 2, 1, 3]
    • i = 0 时,比较第 i 个元素 4 与第 i + 1 个元素 2 的大小,因为 nums[i] > num[i+1],也就是 4 > 2,因此交换它们的位置。
    • i = 1 时,4 > 1,互换位置。
    • i = 2 时,4 > 3,互换位置。最大值 4 被交换到最后一个位置,此时所有元素都参与比较过了,结束第一轮遍历,执行下一轮遍历。
  • 第二轮遍历 [2, 1, 3, 4]
    • i = 0 时,2 > 1,互换位置。
    • i = 1 时,2 < 3,不做交换。次大值 3 被交换到 4 的左边,此时所有元素都参与比较过了,结束第二轮遍历,执行下一轮遍历。
  • 第三轮遍历 [1, 2, 3, 4]
    • i = 0 时,1 < 2,不做交换。此时所有元素都参与比较过了,结束第三轮遍历,
    • 执行了 n - 1 轮遍历,n 为数组的长度,n - 1个元素被交换到正确的位置,第 n 轮遍历时,只剩最后一个元素,因此不用继续进行。

普通的冒泡排序算法

import "fmt"

func main() {
	nums := [4]int{4, 2, 1, 3}
	fmt.Println("原数组:", nums)
	fmt.Println("--------------------------------")
	NormalBubbleSort(nums)
}

func NormalBubbleSort(nums [4]int) {
	for i := 0; i < len(nums)-1; i++ {
		for j := 0; j < len(nums)-i-1; j++ {
			if nums[j] > nums[j+1] {
				nums[j], nums[j+1] = nums[j+1], nums[j]
			}
		}
		fmt.Printf("第 %d 轮遍历后的数组:%v\n", i+1, nums)
	}
	fmt.Println("--------------------------------")
	fmt.Println("排序后的数组:", nums)
}

执行结果:

原数组: [4 2 1 3]
--------------------------------
第 1 轮遍历后的数组:[2 1 3 4]
第 2 轮遍历后的数组:[1 2 3 4]
第 3 轮遍历后的数组:[1 2 3 4]
--------------------------------
排序后的数组: [1 2 3 4]
  • 值得注意的一个地方是第二层循环的条件 j < len(nums)-i-1,为什么会减去 i,因为每轮遍历结束之后,都会有一个元素被固定到后面,因此再进行下一轮的时候,那个元素无须再进行比较。
  • 算法遍历次数为 n -1,每次遍历时元素比较的次数依次为 n - 1、n - 2、n - 3、···、3、2、1,将所有次数求和 = 1 + 2 + 3 + ··· + n - 2 + n - 1= n - 1 * (n - 1 + 1) / 2 = (n² - 1) / 2,因此时间复杂度为 O(n²)。

优化算法

上述例子中,对数组 [4,2,1,3] 进行排序,我们来看看对数组 [4,2,1,3,5] 进行排序,打印数组排序的变化过程中:

原数组: [4 2 1 3 5]
--------------------------------
第 1 轮遍历后的数组:[2 1 3 4 5]
第 2 轮遍历后的数组:[1 2 3 4 5]
第 3 轮遍历后的数组:[1 2 3 4 5]
第 4 轮遍历后的数组:[1 2 3 4 5]
--------------------------------
排序后的数组: [1 2 3 4 5]

不难看出,第三轮与第四轮遍历过程中,都没有进行元素交换位置的操作,对此我们可以推出一个结论,**如果在一轮遍历中,没有进行元素交换位置的操作,那么此时数组的里所有元素都处于正确位置。**根据这个结论,我们可以对算法进行优化:

import "fmt"

func main() {
	nums := [5]int{4, 2, 1, 3, 5}
	fmt.Println("原数组:", nums)
	fmt.Println("--------------------------------")
	BestBubbleSort(nums)
}

func BestBubbleSort(nums [5]int) {
	isSwapped := true
	for isSwapped {
		isSwapped = false
		for i := 0; i < len(nums)-1; i++ {
			if nums[i] > nums[i+1] {
				nums[i], nums[i+1] = nums[i+1], nums[i]
				isSwapped = true
			}
		}
		fmt.Println("遍历后的数组:", nums)
	}
	fmt.Println("--------------------------------")
	fmt.Println("排序后的数组:", nums)
}

执行结果:

原数组: 
--------------------------------
遍历后的数组: [2 1 3 4 5]
遍历后的数组: [1 2 3 4 5]
遍历后的数组: [1 2 3 4 5]
--------------------------------
排序后的数组: [1 2 3 4 5]
  • 定义交换的标记变量 isSwapper,作为第一层循环的条件,每轮遍历开始之后,将标记变量 isSwapper 赋值为 false,如果在比较的过程中发生元素交换,则将标记变量 isSwapper 赋值为 true。直到 isSwapperfalse 时,数组的里所有元素都处于正确的位置,此时可以结束遍历了。
  • 根据执行结果可知,相比普通的算法,优化后的算法少了一轮遍历,这只是在数组元素少的情况下,如果在数组元素多的情况下,对比结果会更明显。
  • 如果数组为 [5,1,2,3,4],那么算法只会遍历一轮,就能得到正确的排序结果。因此优化后的算法,最好的情况下时间复杂度为 O(N),最坏的情况下仍为 O(N²)。

小结

本文首先对冒泡排序进行简单的介绍,然后通过图片演示冒泡排序的思路。普通冒泡排序算法一共要遍历 n - 1 轮,由测试用例 [4 2 1 3 5] 的结果可以推断出 如果在一轮遍历中,没有进行元素交换位置的操作,那么此时数组的里所有元素都处于正确位置。 根据这个结论,对算法进行优化,优化后的算法,最好的情况下时间复杂度为 O(N)。

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

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

相关文章

单商户商城系统功能拆解43—应用中心—门店自提

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…

岗位认识---算法工程师、数据分析

1&#xff0c;算法工程师 1.1 定义 AI算法 算法能力工程能力业务能力 算法工程师 算法职位名称&#xff1a; 算法工程师&#xff08;机器学习大类&#xff09; NLP&#xff08;自然语言处理&#xff09;算法工程师 CV&#xff08;计算机视觉&#xff09;算法工程师 CG&…

Vision Transformer with Deformable Attention

论文地址&#xff1a;https://arxiv.org/abs/2201.00520 代码地址&#xff1a;https://github.com/LeapLabTHU/DAT Abstract Transformers 最近在各种视觉任务上表现出了卓越的性能。大的&#xff0c;有时甚至是全局的感受野赋予了 Transformer 模型比 CNN 模型更高的表示能力…

Kubelet v1.25.x源码——syncLoop

1. 环境说明 Kubernetes源码版本&#xff1a;remotes/origin/release-1.25 Kubernetes编译出来的Kubelet版本&#xff1a;Kubernetes v1.24.0-beta.0.2463ee7799bab469d7 Kubernetes集群实验环境&#xff1a;使用Kubernetes v1.25.4二进制的方式搭建了一个单节点集群 K8S 单节…

RNA-seq 详细教程: `DESeq2` 差异表达分析(7)

学习目标 了解如何设计公式了解如何使用 DESeq2 执行差异表达分析1. DE 分析 差异表达分析工作流程的最后一步是将原始计数拟合到 NB 模型并对差异表达基因进行统计检验。在这一步中&#xff0c;我们本质上是想确定不同样本组的平均表达水平是否存在显著差异。 Paul Pavlidis, …

C语言第二十课:实用调试技巧

目录 前言&#xff1a; 一、Bug&#xff1a; 二、调试&#xff1a; 1.调试是什么&#xff1a; 2.调试的基本步骤&#xff1a; 3. Debug 与 Release &#xff1a; 三、在Windows环境下进行调试&#xff1a; 1.调试环境的准备&#xff1a; 2.调试的快捷键&#xff1a; 3.调试…

【嵌入式硬件芯片开发笔记】HART调制解调器AD5700芯片配置流程

【嵌入式硬件芯片开发笔记】HART调制解调器AD5700芯片配置流程 低功耗HART调制解调器 适用于AD5700/AD5700-1 我的是XTAL_EN接地&#xff0c;CLK_CFG的两个引脚由同一个GPIO控制 初始时HART_CLK_CFG输出低电平 由RTS引脚控制调制/解调。当RTS处于高电平时&#xff0c;为解调&…

React源码(一): render createElement

React源码——渲染&#xff08;render && createElement&#xff09;的简单实现 前言 当前市面上公司对React需求越来越大主, 对于React的源码学习必须提上日程 初始化项目 React脚手架创建项目 全局安装npm install -g create-react-app创建项目create-react-app M…

Web大学生网页作业成品——仿腾讯游戏官网网站设计与实现(HTML+CSS+JavaScript)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

常规构件的立面CAD图案绘制

今天绘制的这个常规构件CAD立面图形呢&#xff0c;用到的都是很基础的CAD命令&#xff0c;有直线、修剪、倒角和旋转等&#xff0c;绘制出来也是很简单的&#xff0c;可以跟着一起操作一下 目标对象 操作步骤 1.使用直线命令绘制出一下线段&#xff0c;形成一个封闭图形 2.用…

【Windows基础】本地安全策略

本地安全策略基本内容 概念 对登陆到计算机上的账号定义一些安全设置&#xff0c;在没有活动目录集中管理的情况下&#xff0c;本地管理员必须为计算机进行设置以确保其安全。 主要是对登录到计算机得账户进行一些安全设置主要影响是本地计算机安全设置 打开方式 三种方式&…

python的distutils、setuptools模块

python中安装包的方式有很多种&#xff1a; 源码包&#xff1a;python setup.py install在线安装&#xff1a;pip install 包名&#xff08;linux&#xff09; / easy_install 包名(window) python包在开发中十分常见&#xff0c;一般的使用套路是所有的功能做一个python模块包…

一个bug,干倒一家估值1.6亿美元的公司

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注&#xff01; 动态类型一时爽&#xff0c;代码重构火葬场。 ——题记 你生涯中写过的最严重的bug是什么&#xff1f; 我们日常接触的bug&#xff0c;无非是页面崩溃&a…

【Zookeeper】学习笔记(一)

Zookeeper学习笔记一、概述1.1、Zookeeper1.2、Zookeeper工作机制1.3、Zookeeper特点1.4、数据结构1.6、应用场景1.6.1、统一命名服务1.6.2、统一配置管理1.6.3、统一集群管理1.6.4、服务器动态上下线1.6.5、软负载均衡二、下载安装2.1、集群规划2.1、集群规部署三、zk选举3.1、…

A-Level商务例题解析及练习

今日知识点&#xff1a; Marketing mix Place Price Promotion Product例题 Q: Discuss the best ways a car manufacturer could use the marketing mix to increase its share of the market. (20)解析 Answers could include: Marketing mix as a framework/process for ide…

基于RFID的物流智能仓储系统的研究(基于STM32的智能仓储系统)

提示&#xff1a;记录做的毕设 文章目录前言一、功能要求:二、代码思路三、硬件说明四、部分代码以及框图等资料五、联系我喜欢请点赞哦&#xff01;前言 随着经济的发展&#xff0c;对企业的生产经营要求提高&#xff0c;企业必须综合利用各种先进技术&#xff0c;在网络与信…

VUE3 响应式 API 之 toRef 与 toRefs

相信各位开发者看到这里时&#xff0c;应该已经对 ref 和 reactive API 都有所了解了&#xff0c;为了方便开发者使用&#xff0c; Vue 3 还推出了两个与之相关的 API &#xff1a; toRef 和 toRefs &#xff0c;都是用于 reactive 向 ref 转换。 各自的作用 这两个 API 在拼写…

Java安全--CC1的补充和CC6

CC1的补充 上一次讲的是cc链的一种形式&#xff0c;这个补充的cc链子是yso的cc链。 这个链子确实比较麻烦&#xff0c;但是和我们下一步要学习的cc6有比较紧的联系。所以做一下补充&#xff0c;值得一提的是这个链子也确实很巧妙 我们看一下两条链子的分歧在哪里&#xff1a; 从…

[附源码]Python计算机毕业设计Django影评网站系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

在地图上基于OpenLayers实现点/线/面静态的绘制显示

在做GIS相关的工作过程中&#xff0c;是离不开矢量的数据的。矢量作为最基础的数据形式&#xff0c;一般通用在各个项目中。在导航软件开发或者应用中&#xff0c;点/线/面的标记&#xff0c;标绘&#xff0c;显示等都是不可缺少的。本文主要是来介绍在地图上基于OpenLayers实现…