我被困在这个任务的第二部分。我想我的算法有问题。 如果我的代码处于良好的方向,请告诉我。 这是我的消息 给定二维整数。该数组由5行10列组成。系统中的每个值都是0到20之间的随机数。必须编写一个程序来执行数组值的排序,如下所示:首先在每列中排列值,使它们按升序排序(从上到下),那么 - 所以可以通过比较同一行中不同列中的值对(“比较词典编纂”)来正确排序列“正确”:比较第一行中两列中的两个值,如果它们与第二行中的值相比是相同的,依此类推,并相应地更改列的顺序(请参阅下面的数组的第三次打印中的示例)。在排序之前和紧急情况的两个阶段之后显示阵列。例如 :
#include "stdio.h"
#include "conio.h"
#include "malloc.h"
#include "stdlib.h"
#define N 5
#define M 10
#define LOW 0
#define HIGH 20
void initRandomArray(int arr[N][M]);
void printArray(int arr[N][M]);
void SortInColumn(int arr[N][M],int m);
void SortColumns(int arr[][M]);
int compareColumns(int arr[][M], int col1, int col2);
void swapColumns( int col1, int col2);
int main()
{
int arr[N][M];
int m;
m=M;
srand((unsigned)time(NULL)); //To clear the stack of Random Number
initRandomArray(arr);
printf("Before sorting:\n");
printArray(arr);
printf("Sorting elements in each column:\n");
SortInColumn(arr,M);
printf("Sorting columns:\n");
SortColumns(arr);
system("pause");
return 0;
}
void initRandomArray(int arr[N][M])
{
int i,j;
for (i=0 ; i<N ; i++)
for (j=0 ; j<M ; j++)
{
arr[i][j]=LOW+rand()%(HIGH-LOW+1);
}
}
void printArray(int arr[N][M])
{
int i,j;
for (i=0 ; i<N ; i++)
{
for (j=0 ; j<M ; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
}
void SortInColumn(int arr[][M],int m)
{
int i,j,k;
int temp;
for( k=0 ; k<m ; ++k) // loops around each columns
{
for(j=0; j<N-1; j++)// Loop for making sure we compare each column N-1 times since for each run we get one item in the right place
{
for(i=0; i < N-1 - j; i++) //loop do the adjacent comparison
{
if (arr[i][k]>arr[i+1][k]) // compare adjacent item
{
temp=arr[i][k];
arr[i][k]=arr[i+1][k];
arr[i+1][k]=temp;
}
}
}
}
printArray(arr);
}
void SortColumns(int arr[][M])
{ int row=0,cols=0,i=0,n=N;
int col1=arr[row][cols];
int col2=arr[row][cols];
compareColumns(arr,col1,col2);
}
int compareColumns(int arr[][M], int col1, int col2)
{
int row=0,cols=0,j;
for ( row=0 ; row < N ; row ++ );
{
for( cols=0 ; cols < M-1 ; cols++)
{
if(arr[row][cols]>arr[row][cols+1])
{
for (j=0 ; j < M-1 ; j++)
{
col1=arr[row][cols];
col2=arr[row][cols+1];
swapColumns(col1 , col2 );
}
}
}
}
printArray(arr);
}
void swapColumns(int col1, int col2)
{
int temp;
temp=col1;
col1=col2;
col2=temp;
}
顺便说一下,compareColumns函数的复杂度是(n ^ 3)?
答案 0 :(得分:0)
该算法太慢,你可以做得更好。
您可以利用每个数字在0到20之间的事实来按线性时间对列进行排序。为此,请使用辅助20x10数组,其中array [i] [j]保存i在原始矩阵的第j列中出现的值的次数。对于您的示例,第一列包含值12,18,13,17,13,因此我们将具有:
array [12] [0] = 1
array [13] [0] = 2
array [18] [0] = 1
array [17] [0] = 1
为具有n个元素的矩阵构建此数组需要O(n)时间(实际上,问题大小始终相同 - 5 * 10 = 50)
建立那个数组,你现在有两种可能性:
a)用排序的列值覆盖原始矩阵。为此,您将进入辅助数组中的每个列j,并扫描值。例如,对于第一列,第一个非零值在数组[12] [0]中,即1,因此在原始数组的第一列中写入“12”,并增加行数,以便您将在正确的位置写下一个值。然后,你会看到数组[13] [0]是2,所以你在原始矩阵中写了两次“13”。你继续为每一列做这个。现在您有一个带有排序列的矩阵,您可以将您的方法应用于列之间的字典排序。
b)由于您希望列之间使用字典顺序,因此您可以看到这相当于按列累计和值对列进行排序。因此,您可以存储另外10个元素的附加数组,其中每个元素是一个结构,包含数组[0..20] [j]的累加和,以及位置j(注意位置i,数组[i] [ j] * i是总和的实际值。对这个10元素数组进行排序非常快,现在你所要做的就是迭代这个排序数组。对于该数组中的每个位置,使用原始索引j(存储在之前的结构中)来索引数组[0] [j],然后使用a)中描述的方法覆盖原始矩阵。这样做的好处是您根本不需要编写任何排序过程,可以使用系统qsort。
此解决方案可以很好地扩展到可接受的值。对于具有N个元素的矩阵,构建辅助数组和累积和数组需要O(N)。对累积和数组进行排序需要与列数成比例的时间,并且覆盖原始数组需要O(N)时间。
请注意,此算法足够快,但对于非常大的值,它会消耗大量内存。您可能想要考虑是否可以通过增加运行时来减少内存使用量。
至于您发布的代码,它是非常不完整的,请尝试为我们提供一些更精致的东西。