冒泡排序原理及C++源码实现


一、原理

比较两个相邻的数,将值大的交换到右边。


二、思路

依次比较两个相邻的数,将较小的数放在左边,较大的数放在右边。具体步骤如下:

  1. 第一次比较,比较第一个数与第二个数,较小的数放在左边,较大的数放在右边。
  2. 第二次比较,比较第二个数与第三个数,较小的数放在左边,较大的数放在右边。
  3. 第三次比较,比较第三个数与第四个数,较小的数放在左边,较大的数放在右边。
  4. 如此继续一次比较,直到最后两个数据比较完成,这时完成一轮的排序。最后一个数是该数组中最大的数。进行下一轮比较的时候,最后一个数值无需参加比较。
  5. 下一轮的比较按照上述规则继续排序,每完成一轮排序,下一轮参加排序的数值就会少1个。

实例:
对数据[1, 4, 2, 6, 7, 3, 5, 10, 9]进行冒泡排序。

  1. 首轮排序
    1)第一次排序:1和4比较,1比4小,无需交换,得到数组[1, 4, 2, 6, 7, 3, 5, 10, 9]
    2)第二次排序:4和2比较,4比2大,交换位置,得到数组[1, 2, 4, 6, 7, 3, 5, 10, 9]
    3)第三次排序:4和6比较,4比5小,无需交换,得到数组[1, 2, 4, 6, 7, 3, 5, 10, 9]
    4)第四次排序:6和7比较,6比7小,无需交换,得到数组[1, 2, 4, 6, 7, 3, 5, 10, 9]
    5)第五次排序:7和3比较,7比3大,交换位置,得到数组[1, 2, 4, 6, 3, 7, 5, 10, 9]
    6)第六次排序:7和5比较,7比5大,交换位置,得到数组[1, 2, 4, 6, 3, 5, 7, 10, 9]
    7)第七次排序:7和10比较,7比10小,无需交换,得到数据[1, 2, 4, 6, 3, 5, 7, 10, 9]
    8)第八次排序:10和9比较,10比9大,交换位置,得到数据[1, 2, 4, 6, 3, 5, 7, 9, 10]
    本轮一共进行了8轮排序,排序结果:[1, 2, 4, 6, 3, 5, 7, 9, 10]

  2. 第二轮排序
    第二轮排序数据以上一轮的排序结果作为基础,由于上一轮最右边一个数值为最大值,所以本轮排序无需与上一轮的最大值进行比价排序。
    1)第一次排序:1和2比较,1比2小,无需交换,得到数组[1, 2, 4, 6, 3, 5, 7, 9, 10]
    2)第二次排序:2和4比较,2比4小,无需交换,得到数组[1, 2, 4, 6, 3, 5, 7, 9, 10]
    3)第三次排序:4和6比较,4比6小,无需交换,得到数组[1, 2, 4, 6, 3, 5, 7, 9, 10]
    4)第四次排序:6和3比较,6比3大,交换位置,得到数组[1, 2, 4, 3, 6, 5, 7, 9, 10]
    5)第五次排序:6和5比较,6比5大,交换位置,得到数组[1, 2, 4, 3, 5, 6, 7, 9, 10]
    6)第六次排序:6和7比较,6比7小,无需交换,得到数组[1, 2, 4, 3, 5, 6, 7, 9, 10]
    7)第七次排序:7和9比较,7比9小,无需位置,得到数组[1, 2, 4, 3, 5, 6, 7, 9, 10]
    本轮一共进行了7轮排序,排序结果:[1, 2, 4, 3, 5, 6, 7, 9, 10]

  3. 依次继续下一轮的排序…


三、冒泡排序特点

  • N个数字排序,总共进行N-1轮排序,每i轮的排序次数为(N-i)次,因此源码实现的时候,可以使用双重循环,外循环控制循环多少轮,内循环控制每一轮的比较次数。

  • 优点:每进行一轮排序,就会少比较一次,因为没进行一轮排序都会找出一个较大值。一定程度上减少算法量。

  • 时间复杂度
    1) 如果数据正序,只需要一轮即可完成排序。需要比较的次数C和记录移动的次数M均达到最小值,即Cmin=n-1, Mmin=0,所以最小的时间复杂度为O(n)。
    2)如果数据反序,需要进行n-1轮排序。每轮排序要进行n-i次比较,每次比较都要移动记录三次来达到交换记录位置。最大时间复杂度为:

在这里插入图片描述
因此冒泡排序总的平均时间复杂度为:O(n2),时间复杂度和数据状况无关。


四、C++源码实现

简单概括:两个循环搞定。

/*
1.从当前元素起,向后依次比较每一对相邻元素,若逆序则交换
2.对所有元素均重复以上步骤,直至最后一个元素
*/
void buddleSort(int arr[], int len)
{
	int temp = 0;
 	int i, j;

	for(i = 0; i < len-1; i++) //外循环为轮数
	{
		for(j=0; j < len-1-i; j++) //内循环为每轮比较次数,第i轮比较len-i次
		{
			//相邻元素,若逆序则交换(升序为左大于右,降序反之)
			if(arr[j] > arr[j+1]) 
			{
				temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
			}
		}	
	}
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值