原地归并排序实现矩阵行排序的问题排查与修复
问题分析与修复方案
核心错误点
矩阵初始化函数类型不匹配
initializeMatrix的参数被声明为int matrix[][MAX_COLS],但你传入的是float类型矩阵,这会导致scanf("%f")读取时出现类型错误,无法正确存储输入值(甚至可能破坏内存)。排序触发逻辑完全失效
在sortMatrixRows中,你调用mergeSort(matrix, i, i, cols)时,start和end参数都是当前行号i。而mergeSort的终止条件是start < end,这会导致递归直接返回,根本没有执行任何排序操作。归并排序的索引逻辑混淆
你的merge和mergeSort函数错误地将start/mid/end当成了行号,而非行内元素的索引。比如merge中用start * cols计算偏移,这完全偏离了目标元素的位置——正确的做法是针对每一行,以该行的起始地址为基准,用行内元素索引访问。
修复后的完整代码
#include <stdio.h> #define MAX_ROWS 100 #define MAX_COLS 100 // 修正参数类型为float矩阵 void initializeMatrix(int row, int col, float matrix[][MAX_COLS]) { printf("Riempi la matrice\n"); for (int i = 0; i < row; ++i) { for (int j = 0; j < col; ++j) { scanf("%f", &matrix[i][j]); } } } // 归并函数:对指定行的[start, end]子数组进行归并,row_start是该行在一维数组中的起始偏移 void merge(float matrix[], int row_start, int start, int mid, int end) { int left_size = mid - start + 1; int right_size = end - mid; // 临时数组存储左右子数组(题目禁止的是辅助二维矩阵,临时一维数组是归并的必要操作) float left[left_size], right[right_size]; // 复制左右子数组到临时空间 for (int i = 0; i < left_size; i++) { left[i] = matrix[row_start + start + i]; } for (int j = 0; j < right_size; j++) { right[j] = matrix[row_start + mid + 1 + j]; } // 归并回原数组对应位置 int i = 0, j = 0, k = start; while (i < left_size && j < right_size) { if (left[i] <= right[j]) { matrix[row_start + k] = left[i]; i++; } else { matrix[row_start + k] = right[j]; j++; } k++; } // 复制剩余元素 while (i < left_size) { matrix[row_start + k] = left[i]; i++; k++; } while (j < right_size) { matrix[row_start + k] = right[j]; j++; k++; } } // 归并排序函数:对指定行的[start, end]范围元素排序 void mergeSort(float matrix[], int row_start, int start, int end) { if (start < end) { int mid = start + (end - start) / 2; mergeSort(matrix, row_start, start, mid); mergeSort(matrix, row_start, mid + 1, end); merge(matrix, row_start, start, mid, end); } } // 遍历每一行执行排序 void sortMatrixRows(float matrix[][MAX_COLS], int rows, int cols) { for (int i = 0; i < rows; i++) { // 第i行的起始偏移为i*cols,对该行0到cols-1的元素排序 mergeSort((float*)matrix, i * cols, 0, cols - 1); } } void printMatrix(float matrix[][MAX_COLS], int row, int col) { for (int i = 0; i < row; ++i) { for (int j = 0; j < col; ++j) { printf("%.2f ", matrix[i][j]); } printf("\n"); } } int main() { int row, col; printf("Insert the number of rows\n"); scanf("%d", &row); printf("Insert the number of columns\n"); scanf("%d", &col); float matrix[MAX_ROWS][MAX_COLS]; initializeMatrix(row, col, matrix); printf("Original Matrix:\n"); printMatrix(matrix, row, col); sortMatrixRows(matrix, row, col); printf("\nSorted Matrix:\n"); printMatrix(matrix, row, col); return 0; }
修复说明
- 修正初始化函数:将参数类型改为
float,确保输入值能正确存储; - 激活排序逻辑:
sortMatrixRows中对每一行调用mergeSort时,传入正确的行内元素范围0到cols-1,触发完整的递归排序; - 重构索引逻辑:用
row_start标记当前行的起始偏移,start/mid/end仅表示行内元素的位置,彻底解决索引混淆问题; - 临时数组的合理性:题目禁止的是辅助二维矩阵,而归并排序必须使用临时一维数组存储子数组,否则无法完成归并操作,这符合题目要求。
测试你提供的示例矩阵,输入后会得到正确的升序每行排序结果。
内容的提问来源于stack exchange,提问作者Davideh
相关产品推荐
相关产品推荐

