1

I am using quick sort algorithm to sort the strings in a 2D array. It works for most of the case but I don't know why the code doesn't work for this case. I had look through many similar questions about quick sort in SO but I still can't figure out what is the problem.

Expected output:

Apple
London
Switch
Table
The

Actual Output:

Apple
London
Table
Switch
The

Here's my code:

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

void quickSort(char arr[][20], int left, int right);

int main(void)
{
    int i;
    char str[][20] = { "Table", "Apple", "The", "Switch", "London"};

    printf("Before:\n");
    for(i=0; i<5; i++) {
        printf("%s\n", str[i]);
    }
    printf("\n");

    quickSort(str, 0, 4);

    printf("After sort:\n");
    for(i=0; i<5; i++) {
        printf("%s\n", str[i]);
    }
    return 0;
}

void quickSort(char arr[][20], int left, int right)
{
    int i, j;
    char *x;
    char tmp[20];

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

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

    if(left < j) {
        quickSort(arr, left, j);
    }
    if(i < right) {
        quickSort(arr, i, right);
    }
}
15
  • 1
    Can you not use qsort? It would save you some time. Commented Feb 23, 2021 at 13:31
  • 1
    This line from your implementation x = arr[(left + (right - left)) / 2]; looks weird. You only keep a pointer to a string while later you copy the strings. And I cannot remember seeing a line like that in common implementations... Looks like you should rewrite yours... Commented Feb 23, 2021 at 13:34
  • @anastaciu I dont know anything about qsort, but thanks for your suggestion. I will try to use it. Commented Feb 23, 2021 at 13:36
  • @SergeBallesta I used x = arr[(left + right) / 2]; at first, but then I found some codes using this instead Commented Feb 23, 2021 at 13:37
  • 1
    @yuncf: what we mean is that if you want to use the median as a pivot, you should strcpy it to make sure that the pointed data is not altered. Commented Feb 23, 2021 at 13:56

2 Answers 2

1

As mentioned, there's a qsort function in C that you can use. Just calculate the size of your array and pass the strcmp function as the 4th argument.


    size_t n = sizeof(str)/sizeof(str[0]);
    qsort(str, n, sizeof(str[0]), (int (*)())strcmp);

Hope that helped!

Sign up to request clarification or add additional context in comments.

3 Comments

Ah, thanks.. I'm kinda new to C myself, and when I was using qsort myself, it seemed to want me to cast to Void.
Thanks, really appreciate it. Here's the warning I seem to get. expected 'int (*)(const void *, const void *)' but argument is of type 'int (*)(const char *, const char *)'
Oh, no! Your solution works, I added it to the answer because I figure you probably know better than me.
0

I don't know why the code doesn't work for this case

Mid point incorrectly calculated:

x = arr[(left + (right - left)) / 2]; // Oops
// This is same as
x = arr[right/2]; // Oops

Use

x = arr[left + (right - left)/2];  // Fixed

Avoid

x = arr[(left + right)/2]; // left + right may overflow

With any type: left, right, left + (right - left)/2 does not overflow when left <= right.

With int left, int right, left + (right - left)/2 does not overflow when values are positive.


Perhaps other issues too.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.