首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

排序——冒泡排序(Bubble sort)

  • 25-03-04 09:41
  • 2646
  • 11587
blog.csdn.net

定义

冒泡排序是一种较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。

这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

算法原理

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

  • 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。 

  • 针对所有的元素重复以上的步骤,除了最后一个。

  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

动画演示

假设我们有一个数列,初始值为[3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48],使用冒泡排序过程如下图所示。

从这个动画过程中,我们可以看到:

第一次冒泡排序完成后,最大值50到达数列的最右边。

第二次冒泡排序完成后,次大值48到达数列的次右边。

以此类推。

算法分析

关键字比较次数记为C,记录移动次数记为M。

时间复杂度

假设数列本身是正序的,那么一趟扫描即完成排序。Cmin=n−1Cmin=n−1,Mmin=0Mmin=0。所需的那么最好的时间复杂度为O(n)O(n)。

假设数列本身是反序的,需要n−1n−1趟排序,每趟排序要进行n−in−i次关键字比较(i⩽i⩽n−1)(1⩽i⩽n−1),且每次比较都必须移动记录三次来达到交换记录位置。在这个情况下,比较和移动次数均达到最大值:Cmax=n∗(n−1)2=O(n2),Mmax=3∗n∗(n−1)2=O(n2)。所需的那么最坏的时间复杂度为O(n2)。

综上所述,冒泡排序总的平均时间复杂度为O(n2)。

空间复杂度

每次移动记录的时候,需要一个附件的空间。所以,冒泡排序的空间复杂度为O(1)。

算法稳定性

冒泡排序算法是稳定的。

因为,冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变。

代码实现

C语言

  1. #define ARR_LEN 255 /*数组长度上限*/
  2. #define elemType int /*元素类型*/
  3. void bubbleSort (elemType arr[], int len) {
  4. elemType temp;
  5. for (int i=0; i-1; i++) {
  6. /* 外循环为排序趟数,len个数进行len-1趟 */
  7. for (int j=0; j-1-i; j++) {
  8. /* 内循环为每趟比较的次数,第i趟比较len-i次 */
  9. if (arr[j] > arr[j+1]) {
  10. /* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
  11. temp = arr[j];
  12. arr[j] = arr[j+1];
  13. arr[j+1] = temp;
  14. }
  15. }
  16. }
  17. }

C++

  1. using namespace std;
  2. template<typename T>
  3. //整数或浮点数皆可使用
  4. void bubble_sort(T arr[], int len) {
  5. T temp;
  6. for (int i = 0; i < len - 1; i++) {
  7. for (int j = 0; j < len - 1 - i; j++) {
  8. if (arr[j] > arr[j + 1]) {
  9. temp = arr[j];
  10. arr[j] = arr[j + 1];
  11. arr[j + 1] = temp;
  12. }
  13. }
  14. }
  15. }

Python3

  1. def bubble_sort(nums):
  2. for i in range(len(nums) - 1): # 这个循环负责设置冒泡排序进行的次数
  3. for j in range(len(nums) - i - 1): # j为列表下标
  4. if nums[j] > nums[j + 1]:
  5. nums[j], nums[j + 1] = nums[j + 1], nums[j]
  6. return nums

JAVA

  1. public static void bubbleSort(int []arr) {
  2. for(int i =1;i
  3. for(int j=0;j
  4. if(arr[j]>arr[j+1]) {
  5. int temp = arr[j];
  6. arr[j]=arr[j+1];
  7. arr[j+1]=temp;
  8. }
  9. }
  10. }
  11. }

算法掌握要求

在OI比赛或者程序设计中,必须掌握冒泡算法,因为这是最简单、最基本的排序算法。

例题

题目链接

http://47.110.135.197/problem.php?id=1035。

题目

在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。

输入

有两行数据,第一行是车厢总数N(不大于10000),第二行是N个不同的数表示初始的车厢顺序。

输出

一个数据,是最少的旋转次数。

样例输入

  1. 4
  2. 4 3 2 1

样例输出

6

题目分析

从题目可知,就是查找逆序对。输入为4 3 2 1,可以知道,逆序对有(4, 3)、(4, 2)、(4, 1)、(3, 2)、(3, 1)和(2, 1),合计一共6对,所以答案为6。

解决方案

可以利用冒泡排序,对输入数据进行排序,记录调整顺序的次数,即为本题结果。

数据集

由于本题是一个模板题,所以数据量比较小,大小为1,000。使用冒泡排序,时间复杂度为O(n2),可以完成任务。

如果数据集进一步扩大,那么冒泡排序就力不从心了,主要是因为时间复杂度太大,必须使用时间复杂度为O(nlogn)的稳定排序算法,比如归并排序。

参考代码

  1. #include
  2. using namespace std;
  3. int bubble_sort(T arr[], int len) {
  4. int ans = 0;
  5. for (int i = 0; i < len - 1; i++) {
  6. for (int j = 0; j < len - 1 - i; j++) {
  7. if (arr[j] > arr[j + 1]) {
  8. int temp = arr[j];
  9. arr[j] = arr[j + 1];
  10. arr[j + 1] = temp;
  11. ans++;
  12. }
  13. }
  14. }
  15. return ans;
  16. }
  17. const int MAXN = 1e3;
  18. int data[MAXN] = {};
  19. int main() {
  20. int n;
  21. cin >> n;
  22. for (int i=0; i
  23. cin >> data[i];
  24. }
  25. cout << bubble_sort(data, n) << endl;
  26. return 0;
  27. }

 

注:本文转载自blog.csdn.net的努力的老周的文章"https://blog.csdn.net/justidle/article/details/104153903"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top