法一:
不采用辅助数组,直接对二维数组进行排序,二维数组直接排序的最大问题是当访问到某行的最后一列时(例如a[n][m]),下个元素也就是下一行的第一个元素的行下标为n+1,列下标为0,也就是a[n+1][0],采用循环不方便直接迭代下标。
设计思路:
先进行行间排序,使得第n行的元素必定<第n-1行的元素;如下所示:
再进行行内排序即可:
代码如下:
//法一:不采用辅助数组的二维数组选择排序
// 行间选择排序
void 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 * col + j) > *(arr + i1 * col + j1)) {
swap(*(arr + i * col + j), *(arr + i1 * col + 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 * col + j) > *(arr + i * col + k)) {
swap(*(arr + i * col + j), *(arr + i * col + k));
}
}
}
}
}
法二:
法一的行间排序用了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;
}
法三:
方法一的代码中既然使用了指针法解引用操作二维数组,那么该二维数组在访问上已经可以当成是一维数组了,是不是就自然没了二维操作上的困难了呢?那么就直接可以按一维数组的方法对任意维度的数组进行排序了(前提是该数组是静态数组,内存连续才可)
#include <iostream>
using namespace std;
// 交换两个整数的值
void swap(int& a, int& b) {
(a != b) && (a = a ^ b, b = a ^ b, a = a ^ b);
}
int Partition(int* arr, int Left, int Right) {
int j = Left, Pivot = *(arr + Left);
for (int i = Left + 1; i <= Right; i++) {
if (*(arr + i) < Pivot) {
j++;
swap(*(arr + i), *(arr + j)); //使得arr[<=j && j != Left] < Pivot
}
}
swap(*(arr + Left), *(arr + j)); //将Pivot放到左区间的右边界,则有Pivot < arr[>j], Pivot > arr[<j]
return j;
}
// 任意多维静态数组快排
void QuickSort(int* arr, int Left, int Right) {
if (Left > Right) return;
int mid = Partition(arr, Left, Right);
QuickSort(arr, Left, mid - 1);
QuickSort(arr, mid + 1, Right);
}
// 打印二维数组
void printArray(int* arr, int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
cout << *(arr + i * col + j) << " ";
}
cout << endl;
}
}
int main() {
int row = 3, col = 4;
int length = row * col;
// 初始化二维数组
int arr[3][4] = { { 12, 11, 13, 5 },
{ 8, 7, 6, 4 },
{ 3, 14, 10, 9 } };
cout << "Original array:" << endl;
printArray(&arr[0][0], row, col);
// 执行排序
QuickSort(&arr[0][0], 0, length - 1);
cout << "Sorted array:" << endl;
printArray(&arr[0][0], row, col);
return 0;
}