当前位置: 首页 > news >正文

哪个公司网站备案快wordpress 推广 插件

哪个公司网站备案快,wordpress 推广 插件,wordpress腾讯云储存,做网站卖机械目录 从最简单的操作开始 如何利用这个原子操作实现一个具体的小目标? 我们来手动模拟一下: 如何从一个小目标扩展到最终目标? 代码的逐步完善 第一阶段:定义函数框架和我们需要的“原子操作” 第二阶段:实现“…

目录

从最简单的操作开始

如何利用这个原子操作实现一个具体的小目标?

我们来手动模拟一下:

如何从一个小目标扩展到最终目标?

代码的逐步完善

第一阶段:定义函数框架和我们需要的“原子操作”

第二阶段:实现“多趟”的逻辑(外层循环)

第三阶段:实现每一趟的“比较交换”逻辑(内层循环)

思考与优化


从最简单的操作开始

📌我们的目标: 将一个无序的数组,例如 [5, 1, 4, 2, 8],变成有序的 [1, 2, 4, 5, 8]

面对这个任务,最直接、最“笨”的思考方式是什么?不是去想什么宏大的整体策略,而是思考:

我能做的最小的、能让数组变得“更”有序一点点的操作是什么?

这个最小的操作就是:只看相邻的两个元素

比如,我们先看 [5, 1]。在最终排好序的数组里,1 肯定在 5 的前面。而现在它们的顺序是错的。怎么办?很简单:把它们换过来!✅

[5, 1, 4, 2, 8] -> 交换 51 -> [1, 5, 4, 2, 8]

这个 “比较相邻元素,如果顺序错了就交换” 的操作,就是冒泡排序算法最核心的原子操作。它非常简单,但通过重复这个简单的操作,我们就能完成整个排序的宏伟目标。


如何利用这个原子操作实现一个具体的小目标?

我们不能漫无目的地到处交换。我们需要一个策略。与其想着如何把整个数组排好序,不如先定一个更小、更容易实现的目标:

“我们能否通过这个原子操作,把数组中最大的那个元素,放到它最终应该在的位置上?”

答案是可以的。最大的元素最终应该在数组的最右边。我们怎么把它“弄”过去呢?

我们可以从数组的左边开始,一路向右,不停地执行我们的“原子操作”。

我们来手动模拟一下:

假设数组是 arr = [5, 1, 4, 2, 8],长度 n = 5

1. 比较 arr[0]arr[1]:

  • [ **5, 1** , 4, 2, 8]

  • 5 > 1,顺序错了,交换。

  • 数组变为: [ **1, 5** , 4, 2, 8]

2. 比较 arr[1]arr[2]:

  • [1, **5, 4** , 2, 8]

  • 5 > 4,顺序错了,交换。

  • 数组变为: [1, **4, 5** , 2, 8]

3. 比较 arr[2]arr[3]:

  • [1, 4, **5, 2** , 8]

  • 5 > 2,顺序错了,交换。

  • 数组变为: [1, 4, **2, 5** , 8]

4. 比较 arr[3]arr[4]:

  • [1, 4, 2, **5, 8** ]

  • 5 < 8,顺序是正确的,什么都不做。

  • 数组保持: [1, 4, 2, 5, 8]

经过这样从左到右的一整轮操作,我们观察结果 [1, 4, 2, 5, 8]。我们成功了吗?

是的!最大的元素 8 已经被我们“护送”到了数组的最末端,也就是它最终应该在的位置。

这个过程就像水中的气泡,最大的那个总是最先“咕噜咕噜”地冒到水面。这就是“冒泡排序”这个名字的由来。我们把这样一整轮从头到尾的比较交换过程,称为一趟 (Pass)


如何从一个小目标扩展到最终目标?

我们已经完成了一趟,成功地将n个元素中最大的一个归位了。现在数组是 [1, 4, 2, 5, | 8] (用 | 把已归位的元素隔开)。

接下来怎么办?

很简单,我们把已经归位的 8 忽略掉,把前面的 [1, 4, 2, 5] 看作是一个规模更小的新问题

我们只需要对这个新的、长度为 n-1 的数组,重复刚才一模一样的操作

👉 我们来模拟第二趟:

  1. 比较 arr[0]arr[1]: [ **1, 4** , 2, 5, | 8] -> 1 < 4,不交换。

  2. 比较 arr[1]arr[2]: [1, **4, 2** , 5, | 8] -> 4 > 2,交换 -> [1, 2, 4, 5, | 8]

  3. 比较 arr[2]arr[3]: [1, 2, **4, 5** , | 8] -> 4 < 5,不交换。

第二趟结束后,数组变为 [1, 2, 4, | 5, 8]。看,现在次大的元素 5 也归位了!

📈 这个逻辑可以一直重复下去。

  • 第三趟,对 [1, 2, 4] 操作,会把 4 归位。

  • 第四趟,对 [1, 2] 操作,会把 2 归位。

  • 当只剩下 1 的时候,它自然就在正确的位置了。

我们需要多少趟呢?对于一个有n个元素的数组,最多需要 n-1 趟,就能把所有元素都排好序。

这个“重复执行”的思路,在编程里天然就对应着循环✅。


代码的逐步完善

现在,我们把上面的推导翻译成代码。

第一阶段:定义函数框架和我们需要的“原子操作”

我们知道肯定需要一个排序函数,并且排序过程中必然要用到“交换”这个原子操作。

// C/C++ 中,要在函数内部修改外部变量的值,需要使用指针
void swap(int* a, int* b) {int temp = *a;*a = *b;*b = temp;
}// 冒泡排序函数的整体框架
// arr 是要排序的数组,n 是数组的长度
void bubbleSort(int arr[], int n) {// 排序逻辑将在这里实现
}

第二阶段:实现“多趟”的逻辑(外层循环)

根据我们的推导,需要重复执行 n-1 趟排序。所以我们需要一个循环来控制这个“趟数”。

void bubbleSort(int arr[], int n) {// 这个外层循环控制总共需要多少“趟” (Pass)// i 表示已经有多少个元素在数组末尾归位了for (int i = 0; i < n - 1; ++i) {// 在这里实现每一趟具体的比较和交换逻辑}
}

第三阶段:实现每一趟的“比较交换”逻辑(内层循环)

在每一趟中,我们从数组的第一个元素开始,向后两两比较。 关键点:比较到哪里为止?

  • 第一趟 (i=0),n个元素都未排序,要比较 n-1 次,检查到 arr[n-2]arr[n-1] 为止。

  • 第二趟 (i=1),最后1个元素已归位,只需要处理前面 n-1 个元素,比较 n-2 次,检查到 arr[n-3]arr[n-2] 为止。

  • i 趟,最后 i 个元素已归位,比较范围是 n-1-i 次。

这个逻辑正好可以用另一个循环,也就是内层循环来实现。

#include <iostream> // 为了方便打印结果void swap(int* a, int* b) {int temp = *a;*a = *b;*b = temp;
}void bubbleSort(int arr[], int n) {// 外层循环,控制“趟数”for (int i = 0; i < n - 1; ++i) {// 内层循环,控制每一趟中的“比较与交换”// 范围是 n - 1 - i,因为每过一趟,末尾就多一个排好的数for (int j = 0; j < n - 1 - i; ++j) {// 这就是我们的“原子操作”if (arr[j] > arr[j+1]) {swap(&arr[j], &arr[j+1]);}}// 我们可以加一句打印,来观察每一趟之后的结果std::cout << "第 " << i + 1 << " 趟排序后: ";for(int k=0; k<n; ++k) std::cout << arr[k] << " ";std::cout << std::endl;}
}

至此,一个可以正确工作的冒泡排序算法就完成了。它完美地复现了我们从第一性原理出发的推导过程。

复杂度分析

最好情况(数组有序):只需要一趟扫描,比较 n−1 次,没有交换 → 时间复杂度: O(n)

最坏情况(数组逆序):每次都需要比较并交换 → 时间复杂度: O(n^2)

空间复杂度:冒泡排序是 原地排序,只需常数个辅助空间 → O(1)

稳定性

冒泡排序是 稳定的

  • 原因:只有在 a[j] > a[j+1] 时才交换,如果相等,不动。

  • 因此相同元素的前后顺序不会被破坏。


思考与优化

我们的算法已经能用了,但它是不是最聪明的?有没有什么情况下它做了“无用功”?

💡设想一个情况:arr = [1, 2, 3, 5, 4]

  • 第一趟后,45交换,数组变为 [1, 2, 3, 4, 5]

  • 此时数组已经完全有序了。

但是,我们上面的代码并不知道这一点。它会继续傻傻地执行第二趟、第三趟、第四趟,虽然在这些趟中一次交换都不会发生。这显然是浪费。

优化的第一性原理: 如果我们发现某一趟从头到尾走下来,一次交换都没有发生,这说明了什么?

这说明数组中每一个元素都已经不大于它的后一个元素了,也就是说,整个数组已经完全有序了!

那么,我们就可以提前结束排序,而不必执行后面多余的趟数。

最终阶段:完善代码,加入优化

我们可以在每一趟开始前,设置一个标志位 swapped = false。如果在这一趟中发生了交换,就把它设为 true

一趟结束后,检查这个标志位。如果它仍然是 false,说明没发生任何交换,我们就可以直接 break 退出外层循环。

// 优化后的冒泡排序
void bubbleSortOptimized(int arr[], int n) {// 外层循环,控制“趟数”for (int i = 0; i < n - 1; ++i) {bool swapped = false; // 设立标志位// 内层循环for (int j = 0; j < n - 1 - i; ++j) {if (arr[j] > arr[j+1]) {swap(&arr[j], &arr[j+1]);swapped = true; // 只要发生一次交换,就将标志位置为true}}// 检查标志位:如果在一整趟中都没有发生交换,说明已经有序if (swapped == false) {std::cout << "在第 " << i + 1 << " 趟后提前结束。" << std::endl;break; // 退出外层循环}std::cout << "第 " << i + 1 << " 趟排序后: ";for(int k=0; k<n; ++k) std::cout << arr[k] << " ";std::cout << std::endl;}
}

这样,我们就从最基本的“交换相邻错误元素”这个原子操作出发,通过“完成小目标 -> 重复操作 -> 发现冗余 -> 加入判断”这一系列逻辑严谨的推导,最终构建出了一个完整且经过优化的冒泡排序算法。

http://www.dtcms.com/a/451849.html

相关文章:

  • 公司网站建设费入哪个科目济南seo网站排名优化工具
  • 怎么通过做网站挣钱广西桂林天气预报15天查询
  • 工程类招聘网站哪个好广东蕉岭县建设局网站
  • 做h5网站设计mes系统
  • 向量存储vs知识图谱:LLM记忆系统技术选型
  • 网站购物系统制作雨辰资讯电子商务类网站开发网站 源文件
  • 做网站被骗首付款怎么报案浙江省工程信息网官网
  • 辽宁建设工程信息网站中国华电集团电子商务平台
  • 建设网站的岗位wordpress 5.2更新了什么
  • 做网站运营需要什么证咨询公司属于什么行业类别
  • 深圳市网站建设公司好不好wordpress自适应手机主题
  • 网站建设思路高端品牌车有哪些
  • 坂田做网站多少钱安徽建设工程实名制网站
  • 长沙人才招聘网站网页图片怎么下载
  • 成都产品网站建设邢台网站建设报价
  • 申请网站域名怎么做网站中国企业黄页大全
  • 拓展公司网站建设一条龙网站建设价格
  • php在网站开发中的作用互联网营销推广公司
  • 知名网站建设策划做微网站的第三方登录
  • 自己做图片上传网站未备案个人网站 如何挣钱
  • 台式机做网站服务器linux wordpress是什么
  • 个人博客网站制作代码学校品牌建设
  • 大数据专业主要学什么西安百度关键词优化
  • 中国建站网专业集团门户网站建设公司
  • 深圳网站建设有没有市场主流搜索引擎有哪些
  • 阿里巴巴网站做方案discuz图片网站模板
  • 扬州网站建设企业10秒折一把古风伞
  • 化工产品东莞网站建设中企动力科技股份有限公司南通分公司
  • 惠州城乡住房建设厅网站平顶山 网站设计
  • 网站建设的内容商标查询天眼查