【问题标题】:Selection Sort pattern [closed]选择排序模式[关闭]
【发布时间】:2015-03-23 12:14:56
【问题描述】:

我得到了以下代码:

#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");
}

SelectionSort

我正在努力寻找任何关于这种排序方法应该如何工作的模式。如果有人能解释一下,我将不胜感激。另外,有没有办法只用 2 个“for”循环来做到这一点?我认为主要问题是我无法围绕 3 个“for”循环来导航矩阵。谢谢。

【问题讨论】:

  • 没有人能帮我解决这个问题吗?
  • 您可能需要考虑将问题标题更改为“了解二维数组上的选择排序”。这可能是对您问题的更准确描述,因此可能会引起更多回复。
  • 在此处发布代码,而不是链接。

标签: loops sorting design-patterns for-loop selection


【解决方案1】:

典型的选择排序适用于一维(即一维)数组。您发布的代码只是使用相同的排序原则对二维数组(即矩阵)进行排序。

我将首先解释选择排序如何在 1D 数组上工作,然后扩展它以解释您的代码如何在 2D 数组上工作。

选择排序

选择排序通过遍历 N 元素数组 A 中的每个元素来工作。在迭代 i 中,0

当 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++)
        {

这对应于一维情况下的最外层循环(上图)。

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

这对应于一维情况下的内循环(上图)。

使用 2 个 for 循环的选择排序 (2D)

这里的技巧是将 4 x 4 2D 数组视为 16 个元素的 1D 数组。这将问题减少到上面的一维排序情况。但是为了让事情顺利进行,我们必须能够使用在数组的“一维”视图上循环的索引来计算这个二维数组中的行和列索引。

二维数组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]

请注意,您可以从A[j] 的索引计算ordsel[k][m] 的行和列索引,如下所示:

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;
    }
}

【讨论】:

    猜你喜欢
    • 2012-06-09
    • 2020-11-25
    • 2012-10-15
    • 1970-01-01
    • 2014-02-22
    • 2013-12-27
    • 2013-04-13
    • 1970-01-01
    • 2013-10-30
    相关资源
    最近更新 更多