冒泡排序 —(超详细版)

最基础的冒泡排序:(C语言)

#include<stdio.h>
int main()
{
	int num = 10;//定义了排序数字的数量
	int a[num];
	for(int i=0;i<num;i++)
	{
		scanf("%d",&a[i]);//输入需要排序的数字
	}
	for(int i=0;i<num-1;i++)//进行冒泡排序
	{
		for(int j=0;j<num-1-i;j++)
		{
			if(a[j]>a[j+1])//对二者值进行交换
			{
				int temp = a[j];
				a[j] = a[j+1];
				a[j+1] = temp;
			}
		}
	}
	for(int i=0;i<num;i++)
	{
		printf("%d ",a[i]);
	}
}

 对于下面的核心代码,外层的排序(也就是排序的总轮数)是比需要排序的数的数量少1的,这个不是记忆性的东西,实际上在纸上写写就可以理解了:比如第一轮第一大的放在最后一位,第二轮第二大的放在倒数第二位...那么依次下去,第九大的放在倒数第九位,这时候其实就不用比了,因为最后一位一定是最小的,算下来一共只比了九次。

这时候有小机灵鬼就会问了:我就想比较10轮会怎么样?——其实不会影响结果,你会发现内层的for循环就直接不执行了,因为不满足j<num-1-i的条件。只比较9轮是因为优化问题,提高代码执行效率。

内层的排序:对于num-1-i,这个减1其实排除掉自己比自己,减i是为了避免与已经排好的那个最大的元素进行比较,提高代码执行效率。if代码块里面是一个交换功能。

for(int i=0;i<num-1;i++)//进行冒泡排序
	{
		for(int j=0;j<num-1-i;j++)
		{
			if(a[j]>a[j+1])
			{
				int temp = a[j];
				a[j] = a[j+1];
				a[j+1] = temp;
			}
		}
	}

基础的冒泡排序其实还可以小优化一下,如果我经历了几轮排序后,我发现元素已经全都排好序了,那就不用进行下面的排序了。那我们应该怎么知道元素排没排好序呢?这时候需要引入一个标志用来判断:

for(int i=0;i<num-1;i++)//进行冒泡排序
	{
		int flag = 0;//定义标志 
		for(int j=0;j<num-1-i;j++)
		{
			if(a[j]>a[j+1])
			{
				flag = 1;//发生了交换 
				int temp = a[j];
				a[j] = a[j+1];
				a[j+1] = temp;
			}
		}
		if(flag == 0) break;//没有发生交换那就break跳出排序 
	}

最后,我的这个排序写的是从小到大排序,如果要从大到小的话,只需要把内层循环if语句里面的大于号改为小于号就行了。

### 冒泡排序算法的超级详细介绍 #### 1. 算法概述 冒泡排序是一种简单直观的比较排序算法。其核心思想是通过多次遍历待排序列表,在每次遍历时依次比较相邻两个元素,将较大的元素逐步向右移动到最终位置[^4]。 #### 2. 排序步骤详解 以下是冒泡排序的具体操作流程: - **外层循环控制轮次**:总共需要进行 `n-1` 轮比较(其中 `n` 是数组长度),因为经过一轮比较后最大的元素会被放置到最后的位置。 - **内层循环完成单轮比较**:在每一轮中,从头开始逐一比较相邻的两个元素。如果前一个元素大于后一个,则交换它们的位置。 - **提前终止条件**:引入一个标志位变量(通常命名为 `flag` 或 `swapped`)。当某一轮中没有任何元素发生交换时,可以认为序列已完全有序,从而提前结束排序过程[^3]。 #### 3. 示例分析 假设有一个未排序数组 `[67, 2, 45, 3, 21, 44, 33, 4]`,我们按照上述规则对其进行冒泡排序。 ##### 初始状态: ```plaintext 原始数据: [67, 2, 45, 3, 21, 44, 33, 4] ``` ##### 第一次迭代: ```plaintext 第一次比较并交换 -> [2, 67, 45, 3, 21, 44, 33, 4] 第二次比较并交换 -> [2, 45, 67, 3, 21, 44, 33, 4] 第三次比较并交换 -> [2, 45, 3, 67, 21, 44, 33, 4] 第四次比较并交换 -> [2, 45, 3, 21, 67, 44, 33, 4] 第五次比较并交换 -> [2, 45, 3, 21, 44, 67, 33, 4] 第六次比较并交换 -> [2, 45, 3, 21, 44, 33, 67, 4] 第七次比较并交换 -> [2, 45, 3, 21, 44, 33, 4, 67] ``` 此时最大值 `67` 已经到达最后一位。 重复以上逻辑直到全部元素按顺序排列为止。 #### 4. 伪代码表示 下面是基于上述原理构建的标准冒泡排序代码本: ```pseudo procedure bubbleSort(A : list of sortable items) n = length(A) for i from 0 to n-1 do swapped = false for j from 0 to n-i-2 do if A[j] > A[j+1] then swap(A[j], A[j+1]) swapped = true end if if not swapped then break end for end procedure ``` 此伪代码清晰展示了如何利用双重嵌套循环结构以及额外的状态标记来实现高效的冒泡排序机制[^1]。 #### 5. Python 实现样例 下面提供了一个完整的Python冒泡排序函数定义及其测试用例展示效果。 ```python def bubble_sort(arr): n = len(arr) for i in range(n - 1): # 控制总的轮次数 flag = False # 初始化本轮是否有过交换动作 for j in range(n - i - 1): # 当前轮次的有效索引范围 if arr[j] > arr[j + 1]: arr[j], arr[j + 1] = arr[j + 1], arr[j] flag = True # 记录发生了交换行为 if not flag: # 如果本轮无任何交换则可停止后续处理 break return arr if __name__ == "__main__": test_data = [67, 2, 45, 3, 21, 44, 33, 4] sorted_result = bubble_sort(test_data.copy()) print(f"Sorted Result:{sorted_result}") ``` 运行该脚本将会得到如下输出结果: ```plaintext Sorted Result:[2, 3, 4, 21, 33, 44, 45, 67] ``` #### 总结 通过对冒泡排序深入剖析可以看出它虽然易于理解和编码实践,但在性能表现上并不理想——最差情况下时间复杂度达到 O()[^2]。然而对于教学目的或者小型数据集而言仍然是非常有价值的工具之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值