Онлайн компилятор C

#include <stdio.h> int main() { const int n = 10; int arr[n]; int i,j,c; for (i = 0; i < 10; i++) { scanf("%d", &arr[i]); } for(i=0;i<9;i++){ for(j=0;j<9;j++){ if (arr[j]%10>arr[j+1]%10){ c=arr[j]; arr[j]=arr[j+1]; arr[j+1]=c; } } } for(i=0;i<10;i++){ printf("%d",arr[i]); if (i!=9){ printf(" "); } } printf("\n"); return 0; }
这段代码的功能是:读入10个整数,然后根据每个数的个位数字(即除以10的余数)进行冒泡排序,最后输出排序后的结果。

代码中存在一个逻辑错误,导致排序可能不正确。

- 内层循环的边界条件 `j < 9` 是正确的,但冒泡排序中,每一轮外层循环后,最大的元素会“冒泡”到末尾,因此内层循环的范围应该随着外层循环的进行而缩小。当前代码中内层循环每次都固定到9,虽然不会导致错误,但效率较低,这不是主要问题。
- 主要问题在于:排序比较的是个位数字,但交换的是整个数组元素。这本身没问题。然而,当两个数的个位数字相同时,它们的相对顺序可能会被改变,但这不是错误,因为题目可能不要求稳定排序。
- 更关键的错误是:外层循环 `for(i=0;i<9;i++)` 只执行了9轮,但冒泡排序需要n-1轮(这里n=10,所以9轮正确)。然而,内层循环每次都是从j=0到j<9,这会导致每一轮都遍历整个数组,但冒泡排序的正确实现中,内层循环应该到 `n-1-i` 为止,否则已经排好的末尾元素会被再次比较和交换,可能破坏已排序的部分。

请检查内层循环的终止条件,思考如何避免对已经排好的末尾元素进行不必要的比较。