Sortowanie struktur

0

HELLO.

chcę opanować sortowanie struktur po określonym polu np ID, Imię, Nazwisko , napisane na trzy sposoby:

:bąbelkowo
: przez wybór
:qucik sort

Mam już algorytm sortujący po ID wykorzystujący metodę bąbelkową.
Czy ktoś może rzucić na niego okiem i go sprawdzić?

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

typedef struct{
int id;
char imie[15];
char nazwisko[15];
}
osoba;

int main()
{

char imie[3][15]={"Zenowefa","Antonina","Maria"};
char nazwisko[3][15]={"Nowak","Iksinski","Igrekowski"};
int i,j;

osoba osoby[3];
osoby[0].id=3;
osoby[1].id=2;
osoby[2].id=1;

for (i=0;i<3;i++) {
for (j=0;j<15;j++) {
osoby[i].imie[j]=imie[i][j];
osoby[i].nazwisko[j]=nazwisko[i][j];
}
}
printf("Przed\n");
for (i=0;i<3; i++)
printf ("osoba [%i]=%s %s\n",osoby[i].id,osoby[i].imie,osoby[i].nazwisko);

printf("Po\n");


int posortowane=1;

osoba temp;
do {
posortowane=1;
for (i=0;i<2; i++) {
if ((osoby[i].id)>(osoby[i+1].id)){
temp.id=osoby[i].id;
for (j=0; j<15; j++) {


temp.id=osoby[i].id;
osoby[i].id=osoby[i+1].id;
osoby[i+1].id=temp.id;

temp.imie[j]=osoby[i].imie[j];
osoby[i].imie[j]=osoby[i+1].imie[j];
osoby[i+1].imie[j]=temp.imie[j];

temp.nazwisko[j]=osoby[i].nazwisko[j];
osoby[i].nazwisko[j]=osoby[i+1].nazwisko[j];
osoby[i+1].nazwisko[j]=temp.nazwisko[j];

}

posortowane=0;
}
}
} while (posortowane==0);
for (i=0;i<3; i++)
printf ("osoba [%i]=%s %s\n",osoby[i].id,osoby[i].imie,osoby[i].nazwisko);
system("PAUSE");
return 0;
} 

Jak zrobić z tego sortowanie na takiej strukturze jak wyżej tylko z wykorzystaniem quick sort, przez wybór?

algorytm sortujący tablicę n wymiarową - qucik sort

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

void mojqsort(int tab[],int lewy,int prawy)
{
   if(lewy<prawy)
   {
      int m=lewy;
      int temp,i;
      for(i=lewy+1;i<=prawy;i++) {
          printf("i=%i lewy=%i prawy=%i m=%i\n",i,lewy,prawy,m);
         if(tab[i]<tab[lewy]) {
            m++;
            temp=tab[m];
            tab[m]=tab[i];
            tab[i]=temp;
            printf("Zamieniam tab[%i]=%i z tab[%i]=%i\n",m,tab[i],i,tab[m]);
         }
      }
        temp=tab[lewy];
        tab[lewy]=tab[m];
        tab[m]=temp;
      printf("Zamieniam po petli tab[%i]=%i z tab[%i]=%i\n",lewy,tab[m],m,tab[lewy]);
      printf("wywolam qsort (tab,%i,%i)\n",lewy,m-1);
      mojqsort(tab,lewy,m-1);
      printf("wywolam qsort (tab,%i,%i)\n",m+1,prawy);
      mojqsort(tab,m+1,prawy);
   }
}

int main()
{
    int tablica[]={1,5,8,3,2,7,9,6,4,0};
    int i;
    for (i=0; i<sizeof(tablica)/sizeof(int);i++) 
		printf("tab[%i]=%i\n",i,tablica[i]);
    printf("Sortowanie...\n");
    mojqsort(tablica,0,sizeof(tablica)/sizeof(int)-1);
    printf("Posortowane!\n");
    for (i=0; i<sizeof(tablica)/sizeof(int);i++) 
		printf("tab[%i]=%i\n",i,tablica[i]);
    system("pause");
    return 0;
}

algorytm sortujący tablicę n - wymiarową przez wybór

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

void ssort(int tab[], int size)
{
    int minIndex,temp,i,j;
    for (i=0; i<size-1; i++) {
	minIndex=i;
	for (j=i+1; j<size; j++) {
	    if (tab[j]<tab[minIndex]) { 
		minIndex=j;
	    }
	}
	if (minIndex>i) {
	    temp=tab[i];
	    tab[i]=tab[minIndex];
	    tab[minIndex]=temp;
	}
    }
}

int main(void)	{
  int tabl[]={3,8,1,4,2,7,9,1,0,3,4,2};
  int i;
  printf("Przed:\n");
  for (i=0; i<sizeof(tabl)/sizeof(int); i++)	{
    printf("tabl[%i]=%i\n",i,tabl[i]);
  }
  ssort(tabl,sizeof(tabl)/sizeof(int));
  printf("Po:\n");
  for (i=0; i<sizeof(tabl)/sizeof(int); i++)	{
    printf("tabl[%i]=%i\n",i,tabl[i]);
  }
  return 0;
}

thx! [soczek]

0

Należy ruszyc głową. Napisz funkcje tzw "komparatory", czyli funkcję która dla 2 elementów zwraca ci np.
-1 jeśli pierwszy jest mniejszy od drugiego
0 jeśli sa równe
1 jeśli pierwszy jest większy od drugiego
Następnie sortuj ale zamiast porównywać za pomocą < albo > użyj tej funkcji. W ten sposób napiszesz funkcję sortującą tylko raz, a jej działanie będzie zależało od funkcji porównującej którą przekażesz.

edit: przykład jak to moze wyglądać

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

struct Osoba
{
  int wiek;
  int wzrost;
  char imie[20];
};
typedef struct Osoba Osoba;

int mlodsza(Osoba o1, Osoba o2) /*komparator porownujacy po wieku, mlodszy = mniejszy*/
{
  return o1.wiek<o2.wiek;
}
int nizsza(Osoba o1, Osoba o2) /*komparator porownujacy po wzroscie, nizsza = mniejsza*/
{
  return o1.wzrost<o2.wzrost;
}

int mini(Osoba* tab, int p, int n, int(*komparator)(Osoba,Osoba));
/*pomocnicza funkcja, wybiera nam indeks minimalnej - na podstawie komparatora - wartosci z tablicy pomiedzy indeksami p i n*/

void wybieranie(Osoba* tab, int n,int(*komparator)(Osoba,Osoba));
/*sortowanie przez wybor, argumenty: tablica, ilosc elementow, funkcja porownujaca dwa elementy*/

int main()
{
  int i;
  char im[2];
  Osoba* tablica = (Osoba*)malloc(sizeof(Osoba)*5); /*tworzymy tablice*/

  for(i=0;i<5;i++) /*wypelniamy wartosciami*/
  {
    tablica[i].wiek = 10-i;
    tablica[i].wzrost = i+150;
    im[0] = 'a'+i;
    im[1]='\0';
    strcpy(tablica[i].imie,im);
  }

  wybieranie(tablica,5,mlodsza);
  printf("Posortowane po wieku\n");
  for(i=0;i<5;i++)
    printf("%s %d %d\n",tablica[i].imie,tablica[i].wiek,tablica[i].wzrost);

  wybieranie(tablica,5,nizsza);
  printf("Posortowane po wzroscie\n");
  for(i=0;i<5;i++)
    printf("%s %d %d\n",tablica[i].imie,tablica[i].wiek,tablica[i].wzrost);

  free(tablica);
  return 0;
}

int mini(Osoba* tab, int p, int n, int(*komparator)(Osoba,Osoba))
{
  int ind=p;
  for (int i=p+1;i<n;i++)
    if (komparator(tab[i],tab[ind]))
      ind=i;
  return ind;
}

void wybieranie(Osoba* tab, int n,int(*komparator)(Osoba,Osoba))
{
  for (int i=0;i<n-1;i++)
    {
      Osoba chw=tab[i];
      int do_zamiany=mini(tab,i,n,komparator);
      tab[i]=tab[do_zamiany];
      tab[do_zamiany]=chw;
    }
}

0

proponowałbym w komparatorach przekazywać wskaźniki do obiektów Osoba zamiast całe obiekty. Będzie wydajniej :).

0

Lepiej referencje żeby nie kombinować za bardzo (o ile to może być C++), ale good point, nie ma sensu ich kopiować ;)

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