我收到了以下代码:
#include <stdio.h>
#include <stdlib.h>
int ordsel[4][4]={ {3,10,12,7},
{33,22,13,21},
{15,6,3,30},
{16,20,27,2}};
void imprimir()
{
for (int k=0;k<4;k++)
{
for (int m=0;m<4;m++)
printf("%d\t",ordsel[k][m]);
printf("\n");
}
}
void ordenar()
{
int cmenor, aux, ia, fmenor;
for (int k = 0 ; k < 4 ; k++)
{
for (int m = 0 ; m < 4 ; m++)
{
fmenor=k;
cmenor=m;
ia=m;
for (int i=k;i<4;i++)
{
for (int j=ia;j<4;j++)
{
if (ordsel[i][j]<ordsel[fmenor][cmenor])
{
cmenor=j;
fmenor=i;
}
}
ia = 0;
}
}
aux = ordsel[k][m];
ordsel[k][m] = ordsel[fmenor][cmenor];
ordsel[fmenor][cmenor] = aux;
}
}
// Pregunta 3 Parcial III 1415-1
main()
{
printf("Programa que Ordenada una Matriz 4 x 4 por el Metodo Selectivo\n");
printf("\n");
printf("\n MATRIZ INICIAL\n");
imprimir();
printf("\n");
ordenar();
printf(" MATRIZ ORDENADA\n");
imprimir();
printf("\n");
system("pause");
}
我很难找到任何关于这种排序方法如何工作的模式。如果有人能解释,我会很感激。另外,有没有办法只使用2个“for”循环?我认为主要的问题是我无法绕过3“for”循环来导航Matrix。谢谢。
答案 0 :(得分:1)
典型的选择排序适用于1维(即1D)阵列。您发布的代码只使用相同的排序原则对2D数组(即矩阵)进行排序。
我将首先解释Selection Sort如何在1D数组上工作,然后扩展它以解释代码如何在2D数组上工作。
选择排序通过循环N元素阵列A中的每个元素来工作。在迭代i,其中0 <= i <1。 N,它找到最小的元素 在A [i]和A [N-1]之间(即,从索引i开始),并将该元素交换为A [i]。
当i = 0时,算法将最小元素交换为A [0],当i = 1时,它将第二个最小元素交换为A [1](因为最小元素已经在A [0]中,它是从A [1]搜索到A [N-1])。对i = 0到N-1执行此操作将对A进行排序。
void selection_sort(int A[], int N)
{
// Loop over each element.
for (int i = 0; i < N; i++)
{
// At each iteration, put the next smallest element
// into the correct position.
// Find the smallest element from A[i] onwards
int min_element_index = i;
for (int j = i + 1; j < N; j++)
{
if (A[j] < A[min_element_index])
min_element_index = j;
}
// Swap the smallest element between A[i] and A[N-1] into A[i]
int tmp = A[i];
A[i] = A[min_element_index];
A[min_element_index] = tmp;
}
}
您可以看到此算法如何工作的可视化here。
您的代码基本上执行以下操作:
1)循环遍历矩阵中的每个元素ordsel [k] [m]:
for (int k=0;k<4;k++)
for (int m=0;m<4;m++)
{
这对应于1D情况下的最外层循环(上图)。
2)在上面的嵌套循环中,考虑元素ordsel [k] [m],它从ordsel [k] [m]开始找到最小的元素:
fmenor=k; // Row index of the smallest element
cmenor=m; // Col index of the smallest element
ia=m; // Starting position of the col index
for (int i=k;i<4;i++)
{
for (int j=ia;j<4;j++) // Start at col ia := m.
{
if (ordsel[i][j]<ordsel[fmenor][cmenor])
{
cmenor=j;
fmenor=i;
}
}
ia=0; // Reset col index to first col when we move to next row
这对应于1D情况下的内环(上图)。
这里的技巧是将4 x 4 2D阵列视为16个元素的1D阵列。这减少了上述1D分拣案例的问题。但是为了使事情有效,我们必须能够使用循环遍历&#34; 1D&#34;来计算此2D数组中的行和col索引。视图的数组。
2D数组ordsel
可以被视为:
int A[] = {3, 10, 12, 7, 33, 22, 13, 21, 15, 6, 3, 30, 16, 20, 27, 2}
现在A[0] == ordsel[0][0]
,A[1] == ordsel[0][1]
,...
特别是A[5] == ordsel[1][0]
,A[6] == ordsel[1][2]
,A[7] == ordsel[1][3]
,...,A[15] == ordsel[3][3]
。
请注意,您可以从ordsel[k][m]
的索引计算A[j]
的行和列索引,如下所示:
int k = j / NUM_COLS; // Row index
int m = j % NUM_COLS; // Col index
我们使用整数截断来舍入j
和模数运算符%
来计算列索引。
int NUM_ROWS = 4;
int NUM_COLS = 4;
void selection_sort_2D()
{
// Loop over 2D array as a 1D array
for (int i = 0; i < NUM_ROWS * NUM_COLS; i++)
{
// The trick is to compute the row and col indices
// from the index i.
int cur_row = i / NUM_COLS; // Index of current row
int cur_col = i % NUM_COLS; // and col
int min_row_idx = cur_row;
int min_col_idx = cur_col;
for (int j = i; j < NUM_ROWS * NUM_COLS; j++)
{
// Similar to how we compute cur_row, cur_col
int k = j / NUM_COLS; // Row index
int m = j % NUM_COLS; // Col index
if (ordsel[k][m] < ordsel[min_row_idx][min_col_idx])
{
min_row_idx = k;
min_col_idx = m;
}
}
// Swap
int tmp = ordsel[cur_row][cur_col];
ordsel[cur_row][cur_col] = ordsel[min_row_idx][min_col_idx];
ordsel[min_row_idx][min_col_idx] = tmp;
}
}