带标志位的Bubble Sort失效,无法降序排序副对角线元素求助
二维数组副对角线冒泡排序问题排查与修复
问题概述
尝试使用带标志位的冒泡排序对二维数组的副对角线元素进行降序排序,但交换操作未生效,输出结果不符合预期。
核心错误点
- 未初始化变量引发越界:排序循环中使用的
j是前序循环的残留值(等于m),访问a[i][j]触发数组越界,行为未定义。 - 冒泡排序逻辑完全错误:未正确遍历副对角线的相邻元素对,比较和交换的索引不符合副对角线规律,且仅执行一轮循环,未完成完整排序流程。
- 类型不匹配丢失数据:用
int temp存储double类型数组元素,导致小数部分丢失,数据失真。 - 输出索引越界:排序后输出时使用
a[i+1][n-i],当i = n-1时,行索引i+1 = n超出数组范围,输出错误数据。 - 副对角线遍历范围错误:原代码用
j < m遍历副对角线,当n < m时会访问行索引为负数的越界元素,正确范围应为k < min(n, m)。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <time.h> int main () { double a[100][100]; int n, m; int i, k; int flag; srand(time(NULL)); // 输入数组行列数 scanf("%d", &n); scanf("%d", &m); // 随机初始化数组 for (i = 0; i < n; i++) { for (int j = 0; j < m; j++) { a[i][j] = 0.09 * (rand() % 1000) - 0.5; } } // 输出原始数组 printf("Array A[N][M]:\n"); for (i = 0; i < n; i++) { printf("\n"); for (int j = 0; j < m; j++) { printf("%6.0f", a[i][j]); } } printf("\n"); // 计算副对角线元素个数(取行列数的较小值) int diag_len = (n < m) ? n : m; // 输出原始副对角线元素 printf("\nElements of the side diagonal are:\n"); for (k = 0; k < diag_len; k++) { printf("%6.0lf", a[n - k - 1][k]); } printf("\n"); // 带标志位的冒泡排序:副对角线降序排列 for (i = 0; i < diag_len - 1; i++) { flag = 0; // 每轮遍历未排序的副对角线元素 for (k = 0; k < diag_len - 1 - i; k++) { // 副对角线当前元素:行=n-k-1,列=k;下一个元素:行=n-(k+1)-1=n-k-2,列=k+1 if (a[n - k - 1][k] < a[n - k - 2][k + 1]) { // 交换元素,使用double类型临时变量避免精度丢失 double temp = a[n - k - 1][k]; a[n - k - 1][k] = a[n - k - 2][k + 1]; a[n - k - 2][k + 1] = temp; flag = 1; // 标记本轮有交换操作 } } if (flag == 0) { break; // 无交换说明已排序完成,提前终止循环 } } // 输出排序后的副对角线元素 printf("\nElements of the sorted side diagonal are:\n"); for (k = 0; k < diag_len; k++) { printf("%6.0lf", a[n - k - 1][k]); } printf("\n"); return 0; }
修正说明
- 副对角线索引规范:副对角线元素满足
行号 + 列号 = n - 1,因此第k个元素的索引为a[n - k - 1][k],遍历范围限制为min(n, m)个元素,避免越界。 - 冒泡排序逻辑修复:采用标准冒泡排序结构,外层循环控制排序轮数,内层循环遍历未排序的相邻元素对,降序排序时将较小的元素向后交换。
- 类型匹配修正:使用
double类型临时变量存储交换值,避免整数类型导致的精度丢失。 - 输出索引修正:沿用正确的副对角线索引输出排序后的元素,确保不越界。
内容的提问来源于stack exchange,提问作者Lvrnnk
相关产品推荐
相关产品推荐

