【问题标题】:Insertion sorting of a 2D array using pointers使用指针对二维数组进行插入排序
【发布时间】:2021-02-21 17:30:06
【问题描述】:

我在编程课上有一个任务 - 使用插入排序方法,使用指针按升序对 2D 数组的奇数行进行排序。到目前为止,我尝试不使用指针,因为我不知道该怎么做。这是我编写的代码,但没有按应有的方式工作。

#include<stdio.h>
main(){
    
    int i,j,n,m;
    
    printf("Introduce n=");
    scanf("%d",&n);
    
    printf("Introduce m=");
    scanf("%d",&m);
    
    int a[n][m];
    
    for(i=0; i<n; i++){
        for(j=0; j<m; j++){
            printf("a[%d][%d]=",i,j);
            scanf("%d",&a[i][j]);
            }
    }
    
    for(i=1; i<n ; i++)
    {
        for(j=1; j<n; j++)
        {
            if(i%2==1)
            {
                for( j = 1 ; j < m ; j ++)
                {
                    int p = j;
                    while(p > 0 && a[i][p] < a[i][p-1])
                    {
                        int aux = a[i][p];
                        a[i][p] = a[i][p-1];
                        a[i][p-1] = aux;
                        p --;
                    }
                }
            }
        }
    }
    
    for(i=0; i<n; i++){
        for(j=0; j<m; j++){
            printf("a[%d][%d]=%d",i,j,a[i][j]);
        }
    }
    
    return 0;
}

【问题讨论】:

  • 你可以只将 i 增加 2 而不是在每次迭代时检查 i 是否为奇数

标签: c sorting multidimensional-array insertion-sort function-definition


【解决方案1】:

对于像你我这样的初学者来说,这不是一件容易的事。此外,还不清楚这些“使用指针”是什么意思。

我可以建议以下演示程序中显示的以下解决方案。 也就是说,有一个单独的函数使用具有指向可变长度数组的指针类型的参数执行排序。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

void sort_by_odd_rows( size_t n, 
                       int ( *first )[n], 
                       int ( *last )[n], 
                       int cmp( const int *, const int *, size_t ) )
{
    if ( first != last && ++first != last )
    {
        for ( int ( *next )[n] = first; ++next != last && ++next != last; )
        {
            int tmp[n];
            memcpy( tmp, *next, n * sizeof( int ) );
            
            int ( *current )[n] = next;
            while ( current != first && cmp( tmp, *( current - 2 ), n ) < 0 )
            {
                memcpy( *current, *( current - 2 ), n * sizeof( int ) );
                current -= 2;
            }
            
            if ( current != next )
            {
                memcpy( *current, tmp, n * sizeof( int ) );
            }
        }
    }
}

int cmp( const int *a, const int *b, size_t n )
{
    size_t i = 0;
    
    while ( i < n && a[i] == b[i] ) ++i;
    
    return i == n ? 0 : ( b[i] < a[i] ) - ( a[i] < b[i] );
}


int main(void) 
{
    size_t m = 10, n = 5;
    int a[m][n];
    
    srand( ( unsigned int )time( NULL ) );
    
    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            a[i][j] = rand() % ( m * n );
        }
    }

    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            printf( "%2d ", a[i][j] );
        }
        putchar( '\n' );
    }
    
    putchar( '\n' );

    sort_by_odd_rows( n, a, a + m, cmp );
    
    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            printf( "%2d ", a[i][j] );
        }
        putchar( '\n' );
    }
    
    putchar( '\n' );

    return 0;
}

程序输出可能看起来像

22  8  2 10  5 
33 21 20 17 45 
 7 20  3  7  5 
47 31 21 29 39 
46 44  0 31  7 
37 43  8 43 23 
 6 15 32  8 25 
39 41 49  9  8 
44 18 30 49 27 
35 46  9  7 28 

22  8  2 10  5 
33 21 20 17 45 
 7 20  3  7  5 
35 46  9  7 28 
46 44  0 31  7 
37 43  8 43 23 
 6 15 32  8 25 
39 41 49  9  8 
44 18 30 49 27 
47 31 21 29 39 

从输出中可以看出,数组的奇数行按升序排序。奇数行排序后的第一个元素是33、35、37、39、47。

至于您的代码,那么它没有多大意义。例如在这两个 for 循环中

    for(j=1; j<n; j++)
    {
        if(i%2==1)
        {
            for( j = 1 ; j < m ; j ++)
            //...

您正在使用相同的变量j

编辑:看来我对你的分配理解有误,你需要按升序对每个奇数行中的元素进行排序。

在这种情况下,排序功能看起来会简单得多。

这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void insertion_sort( int *a, size_t n ) 
{
    for ( int *first = a, *last = a + n; first != last; ++first )
    {
        int tmp = *first;
        int *current = first;
        
        for ( ; current != a && tmp < *( current - 1 ); --current )
        {
                *current = *( current - 1 );
        }
        
        if ( current != first ) *current = tmp;
    }
}

int main(void) 
{
    size_t m = 10, n = 5;
    int a[m][n];
    
    srand( ( unsigned int )time( NULL ) );
    
    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            a[i][j] = rand() % ( m * n );
        }
    }

    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            printf( "%2d ", a[i][j] );
        }
        putchar( '\n' );
    }
    
    putchar( '\n' );

    for ( size_t i = 1; i < m; i += 2 )
    {
        insertion_sort( *( a + i ), n );
    }
    
    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            printf( "%2d ", a[i][j] );
        }
        putchar( '\n' );
    }
    
    putchar( '\n' );

    return 0;
}

程序输出可能看起来像

25 32 47 24 10 
33 39 32 31 33 
46  8 49 35 16 
32 34  9 35 22 
13 35 45 27 45 
17 37  2 13  6 
33 40 38 30 14 
48 15  6 32 49 
39 28  7 39 15 
26 23  2 35  8 

25 32 47 24 10 
31 32 33 33 39 
46  8 49 35 16 
 9 22 32 34 35 
13 35 45 27 45 
 2  6 13 17 37 
33 40 38 30 14 
 6 15 32 48 49 
39 28  7 39 15 
 2  8 23 26 35 

现在每个奇数行都有按升序排序的元素。

【讨论】:

  • 这就是您所说的答案,另外还解释了如何对以奇数开头的行进行逐行和逐列排序。可惜我不能投票两次...
  • 谢谢!我的问题的一个很好的答案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 2020-03-15
  • 2017-12-29
  • 1970-01-01
  • 2013-08-17
  • 2015-09-17
相关资源
最近更新 更多