冒泡排序
图解
tmp图解
 
内容图解







每次循环的次数减少








for循环详解
冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,
一次比较两个元素,如果它们的顺序错误就把它们交换过来。
遍历数列的工作是重复地进行直到没有再需要交换,
也就是说该数列已经排序完成。
在冒泡排序中,外层循环负责控制遍历的轮数,
而内层循环负责在每一轮中进行相邻元素的比较和交换。
通常,冒泡排序的代码如下所示:
for (i = 0; i < sz-1; i++) {
    for (j = 0; j < sz - i - 1; j++) {
        if (arr[j] > arr[j + 1]) {
            // 交换arr[j]和arr[j+1]
        }
    }
}
这里的`sz`是数组`arr`的长度。
现在我们来解释为什么内层循环的`j`需要满足`j < sz - i - 1`。
在每一轮的外层循环中,最大的元素会被放到数组的最后位置。
因此,在下一轮循环开始时,我们不需要再检查已经排好序的部分。
这意味着,对于外层循环的每一次迭代`i`,我们只需要在内层循环中检查前`sz - i - 1`个元素。
例如,如果数组的长度是`5`,那么:
 
 当`i = 0`时,我们需要比较所有`5`个元素,因此`j`的范围是`0`到`4`。
 当`i = 1`时,最大的一个元素已经在数组的最后一个位置,所以我们只需要比较前`4`个元素,`j`的范围是`0`到`3`。
 - 当`i = 2`时,两个最大的元素已经在数组的最后两个位置,我们只需要比较前`3`个元素,`j`的范围是`0`到`2`。
 - 以此类推。
 如果内层循环使用`j < sz - 1`,那么在`i = 1`时,`j`的范围将是`0`到`4`,这是不必要的,因为我们知道`arr[4]`已经是排序好的了。同样,如果内层循环使用`j < sz`,那么在`i > 0`时,它将检查已经排好序的元素,这也是不必要的。
 因此,`j < sz - i - 1`确保了每次外层循环只比较和交换还未排好序的元素,这使得冒泡排序更加高效。
for循环画图详解
下面我用一个简单的图来解释冒泡排序中内层循环的`j`为什么需要满足`j < sz - i - 1`。
 假设我们有一个数组`arr` = `[4, 2, 9, 1, 5]`,它的长度是`sz = 5`。我们将通过冒泡排序对这个数组进行排序。
 在第一轮外层循环中,`i = 0`,我们需要比较所有元素,所以内层循环的`j`范围是`0`到`4`。在这个过程中,最大的元素`9`会被放到数组的最后一个位置。
 在第二轮外层循环中,`i = 1`,最大的元素`9`已经在数组的最后一个位置,所以我们只需要比较前`4`个元素。内层循环的`j`范围现在是`0`到`3`。
 在第三轮外层循环中,`i = 2`,两个最大的元素`9`和`5`已经在数组的最后两个位置,我们只需要比较前`3`个元素。内层循环的`j`范围是`0`到`2`。
 在第四轮外层循环中,`i = 3`,三个最大的元素`9`、`5`和`4`已经在数组的最后三个位置,我们只需要比较前`2`个元素。内层循环的`j`范围是`0`到`1`。
 在第五轮外层循环中,`i = 4`,四个最大的元素`9`、`5`、`4`和`2`已经在数组的最后四个位置,我们只需要比较前`1`个元素。内层循环的`j`范围是`0`到`0`。在这一轮中,内层循环不会执行任何交换,因为`arr[0]`已经是在正确的位置上。
 如果没有`sz - i - 1`这个条件,内层循环会在`i > 0`时继续检查已经排好序的元素,这是不必要的。正确的条件`j < sz - i - 1`确保了每次外层循环只比较和交换还未排好序的元素。
 下面是一个简化的图示,展示了这个过程:
 ```
初始数组: [4, 2, 9, 1, 5]
第一轮后: [2, 4, 9, 1, 5] (9移到末尾)
第二轮后: [2, 4, 1, 5, 9] (9和5移到末尾)
第三轮后: [2, 1, 4, 5, 9] (9、5和4移到末尾)
第四轮后: [1, 2, 4, 5, 9] (9、5、4和2移到末尾)
第五轮后: [1, 2, 4, 5, 9] (数组已经排序完成)
 
代码
//#define _CRT_SECURE_NO_WARNINGS 1
//#include<stdio.h>
从小到大排序 版本1
//void effervescence(int arr[], int sz)
//{
//	for (int i = 0; i < sz - 1; i++)
//	{
//		for (int j = 0; j < sz - 1; j++)
//		{
//			if (arr[j] > arr[j + 1])
//			{
//				int tmp = 0;
//				tmp = arr[j];
//				arr[j] = arr[j + 1];
//				arr[j + 1] = tmp;
//			}
//		}
//	}
//}
//void Print(int arr[], int sz)
//{
//	for (int i = 0; i < sz; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//}
//int main()
//{
//	int arr[] = { 2,3,4,1,6,5,8,7,9,0,10 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	//排序
//	effervescence(arr, sz);
//	//打印
//	Print(arr, sz);
//	return 0;
//}
//版本2
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//从小到大排序 指向同一个空间
void effervescence(int* arr, int sz)
{
	for (int i = 0; i < sz - 1; i++)
	{
		for (int j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = 0;
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 2,3,4,1,6,5,8,7,9,0,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = arr;
	//排序
	effervescence(arr, sz);
	//打印
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));
	}
	return 0;
} 
                










![【LGR-176-Div.2】[yLCPC2024] 洛谷 3 月月赛 I(A~C and G<oeis>)](https://img-blog.csdnimg.cn/direct/f4d557ad127642298a158ac4b51dc3cc.png)







