sortowanie tablicy struktur według danej kategorii

0

Jak mogę posortować całą tablicę struktur według jednej z jej składowych?

struct dane {
	int lp;
	char imie[20];
	char nazwisko[20];
	int rok;
};

Mam strukturę takiego typu i potrzebuję posortować wg roku, imienia oraz nazwiska.
napisałem takie coś:

swapint(int x, int y) {
	int tmp;
	tmp = x;
	x = y; 
	y = tmp;
}

swapchar(char x[], char y[]) {
	char tmp[20];
	strcpy(tmp, x);
	strcpy(x, y);
	strcpy(y, tmp);
}

void bubblesortone(int lata[], char imiona[], char nazwiska[]) {
	int i, j;
	for (i = 0; i < MAX - 1; i++)
	{
		for (j = 0; j < MAX - 1 - i; j++)
		{
			if (lata[j] > lata[j + 1])
			{
				swapint(lata[j], lata[j + 1]);
				swapchar(imiona[j], imiona[j+1]);
				swapchar(nazwiska[j], nazwiska[j+1]);

			}
		}
	}
} 

lecz nie działa.

3

Musisz samemu pisać sortowanie? c ma qsort a c++ std::sort. W obu przypadkach dostarczasz komparator (dla c++ lambde :) )

0
int compare(const void *a,const void *b)
  {
   dane *A=(dane*)a,*B=(dane*)b;
   return strcmp(A->nazwisko,B->nazwisko);
  }
2
  1. swapint jako funkcja jest bezużyteczna, bo argumenty są przekazywane przez wartość. Przeczytaj to: Przekazywanie parametru przez wartość i referencję (oczywiście w C nie ma referencji, ale reszta ma zastosowanie)

  2. Po to masz struktury, żeby w razie zamiany robić tylko 1 swap. Gdyby struktura miała 100 pól to też byś robił 100 razy swap?

void swap(struct dane* left, struct dane* right)
{
    struct dane tmp = *left;
    *left = *right;
    *right = tmp;
}
  1. Jeśli sortowanie nie jest celem ćwiczenia, to zainteresuj się qsort(): http://en.cppreference.com/w/c/algorithm/qsort
0

Pisane na kolanie (tzn na forum, nie kompilowałem)

 
int cmp_data(const void* a, const void* b) 
{
    const struct dane *first = (struct dane*)a;
    const struct dane *second= (struct dane*)b;
    int year_cmp = first->rok - second->rok;
    int fname_cmp = strncmp(first->imie, second->imie, 20);
    int lname_cmp = strncmp(first->nazwisko, second->nazwisko, 20);

    if ( year_cmp < 0 ||
        (!year_cmp && fname_cmp < 0) ||
        (!year_cmp && !fname_cmp && lname_cmp  < 0 ))
        return -1;
    else if (!year_cmp && !fname_cmp  && !lname_cmp)
        return 0;
    return 1;
}

/* ... */

qsort(table, elements_num, sizeof(struct dane), cmp_data)

Jeżeli celem jest napisanie sortowania, a nie posortowanie, to jak jak napisali wyżej zaimplementuj samemu.

2

@nalik - to straszne!

int cmp_data(const void *a,const void *b) 
  {
   const struct dane *A=(struct dane*)a,*B=(struct dane*)b;
   int cmp;
   cmp=(A->rok>B->rok)-(A->rok<B->rok); // A->rok-B->rok - ma nie pełny zasięg np A->rok=INT_MAX; B->rok=-1; owszem `rok` nie powinien ... ale przyzwyczajenie to druga natura
   if(cmp) return cmp;
   cmp=strcmp(A->imie,B->imie);
   if(cmp) return cmp;
   return strcmp(A->nazwisko,B->nazwisko);
  }
0

ok, zrobiłem z tym bubblesort jakoś, dzięki za wszystkie porady :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1