一种思路是先将二维数组转化为一维数组,再利用一维数组的排序算法进行排序,最后转换回二维数组。
另一种思路是直接对二维数组进行排序,利用二维数组在内存中是顺序排放的性质,通过递增指针遍历每个数组元素,进而进行比较移位,完成排序。
实验不是很难,所以直接上冒泡排序和选择排序的代码。所有代码已经用DEV-C++跑过,保证代码的正确性。
使用四个简单的函数实现排序。
#include
#define ROW 3
#define COL 4
void bubble(int a[], int size); //冒泡排序一维
void convert_2D_1D(int arr1[], int arr2[][COL]); //二维转化为一维
void convert_1D_2D(int arr1[], int arr2[][COL]); //一维转化为二维
void ouput_array2(int arr2[][COL]); //输出二维数组
int main(void)
{
int arr[ROW][COL] =
{ {10,5,8,1},
{9,2,6,4},
{3,12,11,7},
};
int size = ROW*COL;
int arr1[size];
convert_2D_1D(arr1, arr); //二维转化为一维
bubble(arr1, size); //一维冒泡排序
convert_1D_2D(arr1,arr); //一维转化为二维
ouput_array2(arr); //输出二维数组
return 0;
}
void convert_2D_1D(int arr1[], int arr2[][COL])
{
int i,j,k=0;
for (i=0; i<ROW; i++)
{
for (j=0; j<COL; j++)
{
arr1[k] = arr2[i][j];
k++;
}
}
}
void convert_1D_2D(int arr1[], int arr2[][COL])
{
int i,j,k=0;
for (i=0; i<ROW; i++)
{
for (j=0; j<COL; j++)
{
arr2[i][j] = arr1[k];
k++;
}
}
}
void bubble(int a[], int size)
{
int i,j,tem;
for (i=0; i<size-1; i++)
{
for (j=size-1; j>i; j--) //从下往上开始排列,从最后一项开始比较移位
{
if(a[j-1]>a[j])
{
tem = a[j];
a[j] = a[j-1];
a[j-1] = tem;
}
}
}
}
void ouput_array2(int arr2[][COL])
{
int i,j,k=1;
printf("新排列的数组:\n");
for (i=0; i<ROW; i++)
{
for (j=0; j<COL; j++)
{
printf("%3d ",arr2[i][j]);
if ( k%4 == 0 )
printf("\n"); //每行输出四个元素
k++;
}
}
}
用指针直接操作数组元素,避免了二维数组索引的使用。
#include
#define ROW 3
#define COL 4
void ouput_array2(int arr2[][COL]); //输出二维数组
int main()
{
int arr[ROW][COL] =
{ {10,5,8,1},
{9,2,6,4},
{7,12,11,3},
};
int *pt = &arr[0][0]; //指针pt指向二维数组的首元素[0][0]
int size = ROW*COL;
int i, j,tem;
//利用二维数组在内存中按顺序排列,使用指针可以将二维数组当作一维数组操作
for (i=0; i<size-1; i++) //n个元素,比较n-1趟
{
for (j=0; j<size-i-1; j++)
{
if(*(pt+j) > *(pt+j+1)) //相邻元素比较移位
{
tem = *(pt+j+1);
*(pt+j+1) = *(pt+j);
*(pt+j) = tem;
}
}
}
ouput_array2(arr);
return 0;
}
void ouput_array2(int arr2[][COL])
{
int i,j,k=1;
printf("新排列的数组:\n");
for (i=0; i<ROW; i++)
{
for (j=0; j<COL; j++)
{
printf("%3d ",arr2[i][j]);
if ( k%4==0 )
printf("\n"); //每行输出四个元素
k++;
}
}
}
采用指针法,此法最为自然且简单。
#include
#define ROW 3
#define COL 4
void ouput_array2(int arr2[][COL]); //打印输出二维数组
int main()
{
int arr[ROW][COL] =
{ {10,5,8,1},
{9,2,6,4},
{7,12,11,3},
};
int *pt = &arr[0][0]; //指针pt指向二维数组的首元素[0][0]
int size = ROW*COL;
int i, j,tem;
//利用二维数组在内存中按顺序排列,使用指针可以将二维数组当作一维数组操作
for (i=0; i<size-1; i++) //n个元素,比较n-1趟
{
int min = i;
for (j=min+1; j<size; j++) //size-i,当i=0时,j最大为size-1,那么循环中的j+1=size使得数组溢出.导致程序出错
{
if(*(pt+min)>*(pt+j)) //先排出最小项
{
tem = *(pt+min);
*(pt+min) = *(pt+j);
*(pt+j) = tem;
}
}
}
ouput_array2(arr); //打印输出新排列的数组
return 0;
}
void ouput_array2(int arr2[][COL])
{
int i,j,k=1;
printf("新排列的数组:\n");
for (i=0; i<ROW; i++)
{
for (j=0; j<COL; j++)
{
printf("%3d ",arr2[i][j]);
if ( k%4==0 )
printf("\n"); //每行输出四个元素
k++;
}
}
}
1.数组是一种将标量数据聚合成更大数据类型的方式。
2.由于C将内存看作一个非常大的字节数组,C语言实现数组的方式十分简单,可以使用指针便捷处理。因此C通常使用指针处理数组的元素,产生指向数组元素的指针,并对指针进行运算。
3.C语言虽然可以使用数组索引对数组元素进行处理,但具有优化功能的C编译器(如GCC)通常会将数组索引转换为指针的间接引用,进而对指针进行运算。这是因为在机器代码中,指针会很容易地被翻译为地址计算。
因此搞清数组与指针的对应关系对于C语言的提高是很有帮助的。
二维数组排序是一维数组排序的拓展,排序思路是相同的,只需要根据二维数组的排列形式稍加处理即可。