I am programming in C. I have an array of structures. I need to print the array in sorted order based on an element of the structure. The main problem where I am stuck is I do not want to modify the original array.

For example: My array is proctab[10]. This is the array of structure named pentry.

struct pentry
{
    int a;
    int b;
    char c;
}

I need to print as follows:

a = 1, b = 2, c = a
a = 2, b = 1, c = d
a = 3, b = 0, c = e
a = 4, b = 1, c = a
a = 4, b = 2, c = a

and so on.. i.e. the result is sorted on a. but if a has same value for two structures in the array, the array should be sorted on b as well.

I want the original array proctab to remain intact.

Is there any way to do this?

有帮助吗?

解决方案 2

To sort the items without messing with the original array, create a second array of references:

struct pentry plist[]= { { 1, 2, 'a' }, { 4, 8, 'z' }, { 2, 7, 'c' }, { 2, 1, 'e' }, { 5, 6, 'b' } ;
struct pentry (* pref)[5] ;

int compare( const struct pentry ** px, const struct pentry ** py )
{
  return ( (** px).a == (** py).a ) ? ( (** py).b - (** px).a ) : ( (** py).a - (** px).a ) ;
}

void dosort( struct pentry ** zdest, struct pentry * asrc, int n )
{
  int i ;
  struct pentry ** fill ;

  for ( i= n, fill= zdest ; ( i -- ) ; ) { *( fill ++)= asrc ++ ; }
  qsort( zdest, n, sizeof( * zdest ), compare ) ;
}

void show_sorted( struct pentry ** aref, int n )
{
  while ( n -- )
  {
    printf("%d %d %c\n", (** aref).a, (** aref).b, (** aref).c ) ;
    ++ aref ;
  }
}

int main()
{
  dosort( pref, plist, sizeof( plist) / sizeof( * plist)) ;
  show_sorted( pref, sizeof( plist) / sizeof( * plist)) ;
  return 0 ;
}

其他提示

You can use qsort.

Edited to include changes to the OP's question.

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

typedef struct tagPentry
{
    int a, b;
    char c;
} pentry;

/* Function used to compare the structs via qsort in 
the main() method */
int compare(const void *a, const void *b)
{
    pentry* p_a = (pentry*)a;
    pentry* p_b = (pentry*)b;

    /* Here, the compare function sorts based on the value of a 
    If p_a.a == p_b.a, then it will also sort by b*/
    if (p_a->a < p_b->a)
        return -1;
    if (p_a->a > p_b->a)
        return 1;
    else /* a is equal, so compare b */
    {
        if (p_a->b < p_b->b)
            return -1;
        if (p_a->b > p_b->b)
            return 1;
        return 0;
    }
}

int main(int argc, char** argv)
{
    /* Original array */
    pentry p[5];
    p[0].a = 1; p[0].b = 2; p[0].c = 'a';
    p[1].a = 4; p[1].b = 8; p[1].c = 'z';
    p[2].a = 2; p[2].b = 7; p[2].c = 'c';
    p[3].a = 2; p[3].b = 1; p[3].c = 'e';
    p[4].a = 5; p[4].b = 6; p[4].c = 'b';

    /* Temp array for output */
    pentry ptemp[5];
    memcpy(ptemp, p, sizeof p);

    /* Sort temp array */
    qsort(ptemp, 5, sizeof(pentry), compare);

    /* Print output */
    for (int i = 0; i < 5; ++i)
    {
        printf("%d %d %c\n", ptemp[i].a, ptemp[i].b, ptemp[i].c);
    }

    return 0;
}

The compare function returns an integer depending on the comparison of the data within the structs. In this example, you can simply subtract the pentry.a values of each struct to determine which is lower. Since we want to compare pentry.b if, and only if, pentry.a for both structs are the same, we use a conditional if statement to compare the pentry.b values when necessary.

With a hope you know sorting a simple integer array,

make a function that take two structures and decide on your own criteria which is greatest or in other words should come first than loop through the structure array with following code,

if( priorityof(arr[j],arr[j+1]) ==0)
SWAP 

your function should return zero if they need to SWAP else return 1

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top