冒泡排序详解

本文详细介绍了冒泡排序的原理和步骤,并通过Java代码展示了冒泡排序的过程,包括原始版本和优化后的版本。优化版减少了不必要的比较,提高了效率。冒泡排序的时间复杂度在最好和最坏的情况下分别为O(n)和O(n^2)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于冒泡排序,相关的网站介绍也比较多,还是写个案例来帮助大家理解

算法原理如下: 

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

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

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

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

 时间复杂度

    1.如果我们的数据正序,只需要走一趟即可完成排序。所需的比较次数C和记录移动次数M均达到最小值,即:Cmin=n-1;Mmin=0;所以,冒泡排序最好的时间复杂度为O(n)。

    2.如果很不幸我们的数据是反序的,则需要进行n-1趟排序。每趟排序要进行n-i次比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:

    

      综上所述:冒泡排序总的平均时间复杂度为:O(n2) ,时间复杂度和数据状况无关。

代码如下:

package ca;

import java.util.Arrays;

public class MP {
	public static void main(String[] args) {
		int a[]={1,8,5,32,45,9,25,36};
		MP.bubbleSort(a);
	}
	 public static void bubbleSort(int arr[]) {
     	int count=0;
	        for(int i =0 ; i<arr.length-1 ; i++) {
	        	//外层控制循环几轮
	            for(int j=0 ; j<arr.length-1-i ; j++) {
	            	//内层循环每轮的数据
	                if(arr[j]>arr[j+1]) {
	                    int temp = arr[j];
	                    arr[j]=arr[j+1];
	                    arr[j+1]=temp;
	                }
	                count++;
	            }
	            System.out.println(Arrays.toString(arr));
	        }
	        System.out.println(count);
	    }
}

排序的步骤如下: 

第一轮排序;

    第一次比较:1和8比较,1小于8,不交换位置      [1,8,5,32,45,9,25,36]   

    第二次比较:8和5比较,8大于5,交换位置         [1,5,8,32,45,9,25,36]

    第三次比较:8和32比较,8小于32,不交换位置    [1,5,8,32,45,9,25,36]

    第四次比较:32和45比较,32小于45,不交换位置   [1,5,8,32,45,9,25,36]

    第五次比较:45和9比较,45大于9,交换位置   [1,5,8,32,9,45,25,36]

    第六次比较:45和25比较,45大于25,交换位置    [1,5,8,32,9,25,45,36]

    第七次比较:45和36比较,45大于36,交换位置  [1,5,8,32,9,25,36,45]

 

第二轮排序;[1,5,8,32,9,25,36,45]

    第一次比较:1和5比较,1小于5,不交换位置     [1,5,8,32,9,25,36,45]

    第二次比较:5和8比较,5小于8,不交换位置     [1,5,8,32,9,25,36,45]

    第三次比较:8和32比较,8小于32,不交换位置    [1,5,8,32,9,25,36,45]

    第四次比较:32和9比较,32大于9,交换位置           [1,5,8,9,32,25,36,45]

    第五次比较:32和25比较,32大于25,交换位置  [1,5,8,9,25,32,36,45]

    第六次比较:32和36比较,32小于36,不交换位置  [1,5,8,9,25,32,36,45]

    第七次比较:36和45比较,36小于45,不交换位置   [1,5,8,9,25,32,36,45] ........

因此第一轮排序完就是对应截图的第一行,后七轮 依次对上一轮排序结果再进行按照以上规则排序

但是我们发现一个问题,如此案例,第二轮排序完就已经排序完成,但是还是会继续比较下去,直到arr.length-1次,后面的比较没有意义的,

因此产生了优化版如下:

package ca;

import java.util.Arrays;

public class MP {
	public static void main(String[] args) {
		int a[]={1,8,5,32,45,9,25,36};
		MP.BubbleSort1(a);
	}
	 public static void bubbleSort(int arr[]) {
     	int count=0;
	        for(int i =0 ; i<arr.length-1 ; i++) {
	        	//外层控制循环几轮
	            for(int j=0 ; j<arr.length-1-i ; j++) {
	            	//arr.length-1-i是关键
	            	//内层循环每轮的数据
	                if(arr[j]>arr[j+1]) {
	                    int temp = arr[j];
	                    arr[j]=arr[j+1];
	                    arr[j+1]=temp;
	                }
	                count++;

	            }
	            System.out.println(Arrays.toString(arr));
	        }
	        System.out.println(count);
	    }
	 
	 public static void BubbleSort1(int [] arr){
		 int count=0;
		 int temp;//临时变量
		 boolean flag;//是否交换的标志
		 for(int i=0; i<arr.length-1; i++){   
			 //表示趟数,一共 arr.length-1 次
			// 每次遍历标志位都要先置为false,才能判断后面的元素是否发生了交换
			 flag = false;
			 for(int j=arr.length-1; j>i; j--){ //选出该趟排序的最大值往后移动
				 if(arr[j] < arr[j-1]){
					 temp = arr[j];
					 arr[j] = arr[j-1];
					 arr[j-1] = temp;
					 flag = true;
					 
				 }
				  count++;
			 }
			 if(!flag) break;
			 System.out.println(Arrays.toString(arr));
		 }
		  System.out.println(count);
	 }

	 
	
}

排序过程如下:

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心寒丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值