法一:
不采用辅助数组,直接对二维数组进行排序,二维数组直接排序的最大问题是当访问到某行的最后一列时(例如a[n][m]),下个元素也就是下一行的第一个元素的行下标为n+1,列下标为0,也就是a[n+1][0],采用循环不方便直接迭代下标。
设计思路:
先进行行间排序,使得第n行的元素必定<第n-1行的元素;如下所示:
再进行行内排序即可:
代码如下:
//法一:不采用辅助数组的二维数组选择排序
int* DirectSort(int*arr, int row, int col) {
//行间选择排序
for (int i = 0; i < row - 1; i++) {
for (int j = 0; j <= col; j++) {
for (int i1 = i + 1; i1 < row; i1++) {
for (int j1 = 0; j1 < col; j1++) {
if (*(arr + i * (row - 1) + j) > *(arr + i1 * row + j1)) {
swap(*(arr + i * (row - 1) + j), *(arr + i1 * row + j1));
}
}
}
}
}
//行内选择排序
for (int i = 0; i < row; i++) {
for (int j = 0; j < col - 1; j++) {
for (int k = j + 1; k < col; k++) {
if (*(arr + i * row + j) > *(arr + i * row + k)) {
swap(*(arr + i * row + j), *(arr + i * row + k));
}
}
}
}
return arr;
}
法二:
法一的行间排序用了4层for循环,也就是时间复杂度为O(n⁴),那有没有办法能减少for循环的层数呢?那就用空间换时间吧,申请一个辅助一维数组,存储该二维数组,也就是降维。
然后直接对一维数组中的数据排序,完成后还原成二维数组输出就行了。
//法二:采用辅助数组的二维数组排序
int* IndirectSort(int arr[][3], int row) {
int temp[row * 3] = {0};
for (int i = 0; i < row; i++) {
for (int j = 0; j < 3; j++) {
temp[3 * i + j] = arr[i][j];
}
}
//冒泡排序
for (int i = 0; i < row * 3 - 2; i++) {
bool sign = false;
for (int j = 3 * row - 1; j > i; j--) {
if (temp[j] < temp[j - 1]) {
sign = true;
swap(temp[j], temp[j - 1]);
}
}
//若本来有序,直接退出排序
if (sign == false) {
break;
}
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < 3; j++) {
arr[i][j] = temp[3 * i + j];
}
}
int* ptr = (int*)arr;
return ptr;
}