Qsort zle sortuje

0

Witam serdecznie.
Potrzebuje pomocy z programem, w ktorym sortuje 100,000 31 cyfrowych kont bankowych z 5 spacjami w srodku. Znalazlem ladnego qsorta w internecie, jednak on nie sortuje prawidlowo (sortuje tak "mniej wiecej" <bardziej mniej="mniej">) i nie jestem wstanie pojac dlaczego.

void quick_string(char items[][38], int count)					// http://www.java2s.com/Code/C/Data-Structure-Algorithm/AQuicksortforstrings.htm
{
  qs_string(items, 0, count-1);
}


void qs_string(char items[][38], int left, int right)
{
  register int i, j;
  char *x;
  char temp[38];

  i = left; j = right;
  x = items[(left+right)/2];

  do {
    while((strcmp(items[i],x) < 0) && (i < right)) i++;
    while((strcmp(items[j],x) > 0) && (j > left)) j--;
    if(i <= j) {
      strcpy(temp, items[i]);
      strcpy(items[i], items[j]);
      strcpy(items[j], temp);
      i++; j--;
   }
  } while(i <= j);

  if(left < j) qs_string(items, left, j);
  if(i < right) qs_string(items, i, right);
}


char tablica[100001][38];

int main()
{
	int tests, il_kont, i, a;
    scanf("%d", &tests);
    while(tests--)
    {
        scanf("%d", &il_kont);
        getchar();						//enter
								
        for(i=0; i < il_kont; i++)
            fgets(tablica[i], 38, stdin);

        quick_string(tablica, il_kont);

.....

tablica jest globalna.

przyklad posortowania:
...
00 01688926 9599 7596 2952 1935
00 03172817 3744 5310 1887 6782
00 02873810 3649 3439 0009 5722
...

0

Na szybko: moim zdaniem dlatego ze zamiast zapisać sobie pivota do nowej zmiennej (zrobic jego kopię) to zapisujesz tylko wskaźnik na oryginał. W ten sposób jeśli pivot zostanie przeniesiony to dostajemy nowego pivota, a to powoduje ze algorytm świruje.
Zamiast

 char *x;
 x = items[(left+right)/2];

Potrzebujesz coś w stylu:

char x[38];
strcpy(x, items[(left+right)/2]);
0

ja bym poprawił tak by nie kopiować takich długaśnych fragmentów pamięci, zamieniłbym to na wskaźniki, a by uniknąć alokowania pamięci zrobiłbym tak:

...
const int MaxNrOfAccounts = 10000;
// jeśli C to: #define MaxNrOfAccounts 10000

char base_tablica[MaxNrOfAccounts ][38];
char *tablica[MaxNrOfAccounts];

int main()
{
     for(int i=0;i<MaxNrOfAccounts; ++i) {
          tablica[i] = base_tablica[i];
          tablica[i][0]=0;
     }
...

Oczywiście trzeba jeszcze poprawić metody sortujące.

0
Shalom napisał(a)

Na szybko: moim zdaniem dlatego ze zamiast zapisać sobie pivota do nowej zmiennej (zrobic jego kopię) to zapisujesz tylko wskaźnik na oryginał. W ten sposób jeśli pivot zostanie przeniesiony to dostajemy nowego pivota, a to powoduje ze algorytm świruje.
Zamiast

 char *x;
 x = items[(left+right)/2];

Potrzebujesz coś w stylu:

char x[38];
strcpy(x, items[(left+right)/2]);

Dziekowac, twoja rada wystarczyla, aby sortowal prawidlowo.

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