【问题标题】:I am trying to print iterations of the sorting function, it seems to work but there are some extra numbers我正在尝试打印排序函数的迭代,它似乎工作但有一些额外的数字
【发布时间】:2021-06-17 13:29:41
【问题描述】:
void SelectionSort(int arr[], int n)
{
    int i, j, min_idx;
    // One by one move boundary of unsorted subarray
    for (i = 0; i < n-1; i++)
    {
        // Find the minimum element in unsorted array
        min_idx = i;
        PrintArray(&arr[i], n);
        for (j = i+1; j < n; j++)
            if (arr[j] < arr[min_idx])
                min_idx = j;
            // Swap the found minimum element with the first element
                Swap(&arr[min_idx], &arr[i]);
    }
}
void PrintArray(int arr[], int n)
{
    int i;
    for (i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

this is the output I'm getting

我正在尝试打印排序过程的每次迭代,我已经分别测试了排序功能和打印功能,它们都可以工作,我尝试将打印功能放在循环中的不同位置,但没有工作。我是 c 和一般编程的新手,所以如果你也可以向我解释这些步骤,我将不胜感激。 谢谢

【问题讨论】:

    标签: c sorting selection-sort function-definition


    【解决方案1】:

    这个电话

    PrintArray(&arr[i], n);
    

    始终使用存储在变量n 中的值作为数组的输出元素数。因此,独立于起始索引i,该函数将尝试准确输出n 元素,从而导致访问数组之外​​的内存。

    你必须写

    PrintArray( &arr[i], n - i );
    

    PrintArray( arr + i, n - i );
    

    但是,您似乎想在每次迭代中输出整个数组。如果是这样,那么你应该写

    PrintArray( arr, n );
    

    还要注意,指定数组元素个数的参数应该使用size_t类型而不是int类型,因为int类型的对象通常不会很大足以在数组中存储可能的元素数量。

    那是你的函数应该被声明为

    void SelectionSort(int arr[], size_t n);
    

    相应地,函数PrintArray 应该声明为

    void PrintArray( const int arr[], size_t n );
    

    注意第一个参数有限定符const,因为数组的元素在函数中没有被改变。

    另外你应该交换数组的两个元素,以防它们不是同一个元素。

    这是一个演示程序。

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    void PrintArray( const int [], size_t );
    void Swap( int *, int * );
    
    void SelectionSort( int arr[], size_t n )
    {
        for ( size_t i = 1; i < n; i++ )
        {
            PrintArray( arr + i - 1, n - i - 1 );
            
            size_t min_idx = i - 1;
    
            for ( size_t j = i; j < n; j++ )
            {
                if ( arr[j] < arr[min_idx] ) min_idx = j;
            }           
    
            if ( min_idx != i - 1 ) Swap( &arr[min_idx], &arr[i-1] );
        }
    }
    
    void PrintArray( const int arr[], size_t n )
    {
        for ( size_t i = 0; i < n; i++ )
        {
            printf( "%d ", arr[i] );
        }       
        putchar( '\n' );
    }
    
    void Swap( int *a, int *b )
    {
        int tmp = *a;
        *a = *b;
        *b = tmp;
    }
    
    int main(void) 
    {
        enum { N = 10 };
        int a[N];
        
        srand( ( unsigned int )time( NULL ) );
        
        for ( size_t i = 0; i < N; i++ )
        {
            a[i] = rand() % N;
        }
        
        SelectionSort( a, N );
        
        PrintArray( a, N );
        
        return 0;
    }
    

    程序输出是

    2 2 9 2 3 9 3 2 
    2 9 2 3 9 3 2 
    9 2 3 9 3 2 
    9 3 9 3 2 
    3 9 3 9 
    9 3 9 
    9 9 
    9 
    
    2 2 2 2 2 3 3 5 9 9 
    

    【讨论】:

    • 如果没问题,我还有另一个后续问题,有没有办法打印已排序的元素以及未排序的元素,以便它有更多的方形而不是三角形?
    • @RodE 您需要更改函数 PrintArray 删除语句 putchar( '\n' );并在调用该函数两次后放置语句。第一个为 PrintArray( a, i );第二次为 PrintArray(a + i, n - i);
    • @RodE 或者正如我在回答中已经指出的那样,只需输出整个数组而不更改函数 PrintArray。
    • 再次感谢弗拉德
    【解决方案2】:

    请注意,您将从第 i'th 元素开始的数组传递给您的打印函数,但您的打印函数通过将 i 初始化为 @ 中的 0 来期望数组具有 n 元素987654325@ 循环。结果,您实际上是在数组之外打印元素。这也解释了为什么您总是打印n 元素,并且每次附加数字的数量都会增加。

    我建议你在你的程序中使用valgrind。它显示了您的程序中可能发生的各种内存错误。这是访问分配给您的内存之外的内存的示例,它会捕获这些内存。它还会在运行结束时告诉您内存泄漏(即您没有释放的内存)。

    此外,即使代码块的长度为 1 个命令,也不要在代码中省略花括号。它使您的代码的可读性大大降低,并可能导致错误。

    void PrintArray(int arr[], int n) { 
        int i; 
        for (i = 0; i < n; i++) {
            printf("%d ", arr[i]); 
        }
        printf("\n"); 
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-06
      • 2019-11-13
      • 1970-01-01
      • 2018-11-06
      • 2020-06-04
      相关资源
      最近更新 更多