【问题标题】:How can do insertion sorting, but to print the highest to the lowest GPA?怎么能做插入排序,但要打印从最高到最低的 GPA?
【发布时间】:2020-09-23 19:29:35
【问题描述】:

我被要求编写一个代码,进行插入排序以将 GPA 从最高到最低排序。 这是我的代码,它为我打印了相同的输入列表:(没有发生任何变化!所以,gpa最低的学生应该被排序到数组的末尾。输出只是对没有ID的GPA进行排序. 重点在这里,我需要按学生的 GPA 排序,并确保他们的 ID 在旁边。

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

typedef struct
{
   int ID;
   float GPA;
}STUDENT;

// method that sorts the array in descending order of GPA
void InsertionSortModified(STUDENT *StuAry,int N)
{
    int walk;
    float temp;
    bool located;

    for(int current =1; current <= N; current++){
        located=false;
        temp = StuAry[current].GPA;

        for(walk = current-1; walk>=0 && !located;)
        {
           if( temp > StuAry[walk].GPA)
           {
              StuAry[walk+1].GPA = StuAry[walk].GPA;
              walk --;
           }
            else
                located=true;
            StuAry[walk+1].GPA=temp;
        }
    }
}


void printArray(STUDENT *StuAry,int N)
{
   for(int i=0;i<N;i++)
       printf("%d %.2f\n",StuAry[i].ID,StuAry[i].GPA);
   printf("\n");
}

// testing main method
int main()
{
   STUDENT StuAry[]={{1,65.2},{2,75.3},{3,34.5},{4,99.9}};
   int N=4;
   printf("Before Sorting: \n");
   printArray(StuAry,N);
   InsertionSortModified(StuAry,N);
   printf("After Sorting: \n");
   printArray(StuAry,N);

   return 0;

}

//Now the problem is the output:
//Before sorting:
//1 56.20
//2 75.30
//3 34.50 
//4 99.90

//After sorting: //Notice her the integer(ID) it's not changing

//1 99.90
//2 75.30
//3 65.20
//4 34.50

【问题讨论】:

    标签: c sorting struct insertion-sort function-definition


    【解决方案1】:

    添加此答案以保持简单易懂 我没有从第 0 个索引开始,而是从 N-1 索引开始,并与大多数元素进行比较,简而言之,这与通用插入排序相反。

    #include <stdio.h>
    
    typedef struct
    {
       int ID;
       float GPA;
    
    }STUDENT;
    
    void InsertionSortModified(STUDENT *StuAry,int N) 
    { 
        int i, key, j; 
        STUDENT pnt;
        for (i = N-2; i >= 0; i--) {
            pnt = StuAry[i];
            key = StuAry[i].GPA; 
            j = i + 1; 
    
            while (j < N && StuAry[j].GPA > key) { 
                StuAry[j - 1] = StuAry[j]; 
                j = j + 1; 
            } 
            StuAry[j - 1] = pnt; 
        } 
    } 
    
    void printArray(STUDENT *StuAry,int N)
    {
       for(int i=0;i<N;i++)
           printf("%d %.2f\n",StuAry[i].ID,StuAry[i].GPA);
       printf("\n");
    }
    
    // testing main method
    int main()
    {
       STUDENT StuAry[]={{1,65.2},{2,75.3},{3,34.5},{4,99.9}, {5, 12.21}, {6, 98}};
       int N=6;
       printf("Before Sorting: \n");
       printArray(StuAry,N);
       InsertionSortModified(StuAry,N);
       printf("After Sorting: \n");
       printArray(StuAry,N);
    
       return 0;
    
    }
    
    

    【讨论】:

    • 我做了,但是输出很乱,你能检查一下吗?
    • 检查这个,保持简单,我从右到左遍历。比较元素,如果更高,则将其向左移动,依此类推。
    【解决方案2】:

    步行 >=0

    • 你的温度应该是一个浮点数

    【讨论】:

    • 我做了更改,但输出仍然不正确:C 请再次检查
    【解决方案3】:

    据我了解,对于初学者,您需要按数据成员GPA 对 STUDENT 类型的对象进行排序。这意味着在排序过程中,如果需要,您需要交换整个对象,而不是交换数据成员 FPA 的值。

    所以这些陈述

    temp = StuAry[current].GPA;
    //...
    StuAry[walk+1].GPA = StuAry[walk].GPA;
    //...
    StuAry[walk+1].GPA=temp;
    

    没有意义。

    在这个for循环中

        for(walk = current-1; walk>=0 && !located;)
        {
           if( temp > StuAry[walk].GPA)
           {
              StuAry[walk+1].GPA = StuAry[walk].GPA;
              walk --;
           }
            else
                located=true;
            StuAry[walk+1].GPA=temp;
        }
    

    声明

            StuAry[walk+1].GPA=temp;
    

    在循环的每次迭代中执行,因为它不是 else 语句的子语句

            else
                located=true;
    
            StuAry[walk+1].GPA=temp;
    

    该函数可以如下面的演示程序所示。

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    typedef struct
    {
       int ID;
       float GPA;
    }STUDENT;
    
    void insertion_sort( STUDENT a[], size_t n )
    {
        for ( size_t i = 1; i < n; i++ )
        {
            STUDENT current = a[i];
    
            size_t j = i;
            while ( j != 0 && a[j-1].GPA < current.GPA )
            {
                a[j] = a[j-1];
                --j;
            }
    
            if ( j != i ) a[j] = current;
        }
    }
    
    int main(void) 
    {
        enum { N = 10 };
        STUDENT a[N];
    
        srand( ( unsigned int )time( NULL ) );
    
        for ( size_t i = 0; i < N; i++ )
        {
            a[i].ID  = ( int )i;
            a[i].GPA = ( rand() % N ) / ( float )N;
        }
    
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "(%d, %.1f) ", a[i].ID, a[i].GPA );
        }
        putchar( '\n' );
    
        insertion_sort( a, N );
    
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "(%d, %.1f) ", a[i].ID, a[i].GPA );
        }
        putchar( '\n' );
    
        return 0;
    }
    

    程序输出可能看起来像

    (0, 0.4) (1, 0.4) (2, 0.1) (3, 0.7) (4, 0.3) (5, 0.7) (6, 0.9) (7, 0.1) (8, 0.2) (9, 0.0) 
    (6, 0.9) (3, 0.7) (5, 0.7) (0, 0.4) (1, 0.4) (4, 0.3) (8, 0.2) (2, 0.1) (7, 0.1) (9, 0.0) 
    

    如果您希望如果两个对象具有相同的 GPA 将按照 ID 的升序排序,那么 while 语句中的条件可以如下所示。

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    typedef struct
    {
       int ID;
       float GPA;
    }STUDENT;
    
    void insertion_sort( STUDENT a[], size_t n )
    {
        for ( size_t i = 1; i < n; i++ )
        {
            STUDENT current = a[i];
    
            size_t j = i;
            while ( j != 0 && 
                    ( a[j-1].GPA < current.GPA || 
                      ( !( current.GPA < a[j-1].GPA ) && current.ID < a[j-1].ID  ) ) )
            {
                a[j] = a[j-1];
                --j;
            }
    
            if ( j != i ) a[j] = current;
        }
    }
    
    int main(void) 
    {
        enum { N = 10 };
        STUDENT a[N];
    
        srand( ( unsigned int )time( NULL ) );
    
        for ( size_t i = 0; i < N; i++ )
        {
            a[i].ID  = ( int )i;
            a[i].GPA = ( rand() % N ) / ( float )N;
        }
    
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "(%d, %.1f) ", a[i].ID, a[i].GPA );
        }
        putchar( '\n' );
    
        insertion_sort( a, N );
    
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "(%d, %.1f) ", a[i].ID, a[i].GPA );
        }
        putchar( '\n' );
    
        return 0;
    }
    

    程序输出可能看起来像

    (0, 0.0) (1, 0.7) (2, 0.8) (3, 0.8) (4, 0.4) (5, 0.6) (6, 0.0) (7, 0.3) (8, 0.7) (9, 0.2) 
    (2, 0.8) (3, 0.8) (1, 0.7) (8, 0.7) (5, 0.6) (4, 0.4) (7, 0.3) (9, 0.2) (0, 0.0) (6, 0.0) 
    

    例如前两条 GPA 相同的记录

    (2, 0.8)(3, 0.8)

    按ID升序排列。

    您可以编写一个通用排序函数,该函数接受提供所需条件的函数。例如

    void insertion_sort( STUDENT a[], size_t n, int cmp( const void *, const void * ) )
    {
        for ( size_t i = 1; i < n; i++ )
        {
            STUDENT current = a[i];
    
            size_t j = i;
            while ( j != 0 && cmp( &a[j-1], &current ) > 0 )
            {
                a[j] = a[j-1];
                --j;
            }
    
            if ( j != i ) a[j] = current;
        }
    }
    

    所以你只需要提供一个比较函数来比较数组的两个元素。

    这是一个演示程序

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    typedef struct
    {
       int ID;
       float GPA;
    }STUDENT;
    
    int cmp_ascending( const void *a, const void *b )
    {
        const STUDENT *left  = a;
        const STUDENT *right = b;
    
        return ( right->GPA < left->GPA ) - ( left->GPA < right->GPA );
    }
    
    int cmp_descending( const void *a, const void *b )
    {
        const STUDENT *left  = a;
        const STUDENT *right = b;
    
        return ( left->GPA < right->GPA ) - ( right->GPA < left->GPA );
    }
    
    void insertion_sort( STUDENT a[], size_t n, int cmp( const void *, const void * ) )
    {
        for ( size_t i = 1; i < n; i++ )
        {
            STUDENT current = a[i];
    
            size_t j = i;
            while ( j != 0 && cmp( &a[j-1], &current ) > 0 )
            {
                a[j] = a[j-1];
                --j;
            }
    
            if ( j != i ) a[j] = current;
        }
    }
    
    int main(void) 
    {
        enum { N = 10 };
        STUDENT a[N];
    
        srand( ( unsigned int )time( NULL ) );
    
        for ( size_t i = 0; i < N; i++ )
        {
            a[i].ID  = ( int )i;
            a[i].GPA = ( rand() % N ) / ( float )N;
        }
    
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "(%d, %.1f) ", a[i].ID, a[i].GPA );
        }
        putchar( '\n' );
    
        insertion_sort( a, N, cmp_ascending );
    
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "(%d, %.1f) ", a[i].ID, a[i].GPA );
        }
        putchar( '\n' );
    
        insertion_sort( a, N, cmp_descending );
    
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "(%d, %.1f) ", a[i].ID, a[i].GPA );
        }
        putchar( '\n' );
    
        return 0;
    }
    

    它的输出可能看起来像

    (0, 0.5) (1, 0.9) (2, 0.6) (3, 0.3) (4, 0.2) (5, 0.6) (6, 0.1) (7, 0.3) (8, 0.0) (9, 0.3) 
    (8, 0.0) (6, 0.1) (4, 0.2) (3, 0.3) (7, 0.3) (9, 0.3) (0, 0.5) (2, 0.6) (5, 0.6) (1, 0.9) 
    (1, 0.9) (2, 0.6) (5, 0.6) (0, 0.5) (3, 0.3) (7, 0.3) (9, 0.3) (4, 0.2) (6, 0.1) (8, 0.0) 
    

    首先对数组进行升序排序,然后再降序排序。

    【讨论】:

      猜你喜欢
      • 2018-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-16
      • 2011-04-22
      • 1970-01-01
      相关资源
      最近更新 更多