二维数组的冒泡/选择排序(两种实现方法)

一、思路

1.降维排序

一种思路是先将二维数组转化为一维数组,再利用一维数组的排序算法进行排序,最后转换回二维数组。

2.指针运算

另一种思路是直接对二维数组进行排序,利用二维数组在内存中是顺序排放的性质,通过递增指针遍历每个数组元素,进而进行比较移位,完成排序。

二、Show me the code.

实验不是很难,所以直接上冒泡排序和选择排序的代码。所有代码已经用DEV-C++跑过,保证代码的正确性。

1.冒泡排序

(1)降维排序

使用四个简单的函数实现排序。

#include <stdio.h>
#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++;
	  	}
	 }
}
		
		

(2)指针法

用指针直接操作数组元素,避免了二维数组索引的使用。

#include <stdio.h>
#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++;
	  	}
	 }
}
	

2.选择排序

采用指针法,此法最为自然且简单。

#include <stdio.h>
#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++;
	  	}
	 }
}

三、补充知识

C语言中数组的特点

1.数组是一种将标量数据聚合成更大数据类型的方式。
2.由于C将内存看作一个非常大的字节数组,C语言实现数组的方式十分简单,可以使用指针便捷处理。因此C通常使用指针处理数组的元素,产生指向数组元素的指针,并对指针进行运算。
3.C语言虽然可以使用数组索引对数组元素进行处理,但具有优化功能的C编译器(如GCC)通常会将数组索引转换为指针的间接引用,进而对指针进行运算。这是因为在机器代码中,指针会很容易地被翻译为地址计算
因此搞清数组与指针的对应关系对于C语言的提高是很有帮助的。

四、总结

二维数组排序是一维数组排序的拓展,排序思路是相同的,只需要根据二维数组的排列形式稍加处理即可。

猜你喜欢

转载自blog.csdn.net/weixin_44605210/article/details/107429110