CS157 Qsort

# Honesty

• OK, really, programmers very rarely write code to do sorting.
• In the shell, they generally use the `sort` command.
• In C, they generally use `qsort`.

# The Idiot Savant

• Imagine that you had a semi-brilliant assistant who was very good at sorting.
• However, your assistant doesn’t know alphabetical order.
• He can do everything that’s needed for sorting except actually determine if, say, “Jay” comes before “David”.
• Therefore, he frequently comes to you, asking if this word comes before this other word.
• `qsort` is like that.

# qsort

```#include <stdlib.h>

void qsort(void *base, int count, int size, compare);
```
• base - a pointer to the beginning of the array that needs sorting
• count - how many things are in the array
• size - the size of each thing in the array
• compare - a function that compares two things
• Really—just two things. It only has to compare a single pair of items.

# Calling qsort

```    int numbers[] = {11,2,1957,10,14,1956,11,1,1955};
qsort(numbers, 9, sizeof(int), compare);
```

or

```    struct Who { char name[20]; double gpa; };
struct Who faculty[] = {
{"Jack",3.9}, {"Bruce",3.5}, {"Darrell",0.2}, {"Dale",2.9}
};
qsort(faculty, 4, sizeof(struct Who), compare_gpa);
```

# The comparison function

```    int compare(const void *av, const void *bv) {
const int *a = av, *b = bv;
if (*a < *b) return -1;
if (*a > *b) return 1;
return 0;
}
```
• The function is given two `const void *` pointers.
• Convert the generic pointers to pointers of the right type.
• `const` means that we won’t change those values.

# The comparison function

```    int compare(const void *av, const void *bv) {
const int *a = av, *b = bv;
if (*a < *b) return -1;
if (*a > *b) return 1;
return 0;
}
```
• If the first value should go before the second value, return -1.
• If the first value should go after the second value, return 1.
• If they’re equal, return 0.

(Really, any negative/positive/zero values are good enough.)

# The comparison function

```    int compare(const void *av, const void *bv) {
const int *a = av, *b = bv;
if (*a < *b) return -1;
return *a > *b;
}
```

This does the same thing as the previous example.

# A comparison function for strings

```    int compare(const void *av, const void *bv) {
const char *a = av, *b = bv;
return strcmp(a,b);          // perfect!
}
```

The return values for a `qsort` comparison function are exactly like the return values of `strcmp`.

# Comparing structs

```    struct Who { char name[20]; double gpa; };

int compare_gpa(const void *av, const void *bv) {
const struct Who *a = av, *b = bv;
if (a->gpa < b->gpa) return -1;
if (a->gpa > b->gpa) return 1;
return 0;
}
```

This comparison function compares two structs, comparing them by GPA.

# Sorting ints

```int compare(const void *av, const void *bv) {
const int *a = av, *b = bv;
if (*a < *b) return -1;
if (*a > *b) return 1;
return 0;
}

int main() {
int numbers[] = {11,2,1957,10,14,1956,11,1,1955};
qsort(numbers, 9, sizeof(int), compare);
for (int i=0; i<9; i++)
printf("%d\n", numbers[i]);
}
```
```1
2
10
11
11
14
1955
1956
1957
```

# Sorting structs

```struct Who { char name[20]; double gpa; };
int compare_gpa(const void *av, const void *bv) {
const struct Who *a = av, *b = bv;
if (a->gpa < b->gpa) return -1;
if (a->gpa > b->gpa) return 1;
return 0;
}
int compare_name(const void *av, const void *bv) {
const struct Who *a = av, *b = bv;
return -strcmp(a->name,b->name);
}
int compare_gpaname(const void *av, const void *bv) {
const struct Who *a = av, *b = bv;
if (a->gpa < b->gpa) return -1;
if (a->gpa > b->gpa) return 1;
return -strcmp(a->name,b->name);
}

int main() {
struct Who faculty[] = {
{"Jack",3.999}, {"Bruce",3.5}, {"Darrell",3.5}, {"Dale",2.9}
};
qsort(faculty, 4, sizeof(struct Who), compare_gpaname);
for (int i=0; i<4; i++)
printf("%-8s %.2f\n", faculty[i].name, faculty[i].gpa);
}
```
```Dale     2.90
Darrell  3.50
Bruce    3.50
Jack     4.00
```

User: Guest

Check: HTML CSS
Edit History Source

Modified: 2018-04-20T13:22

Apply to CSU | Contact CSU | Disclaimer | Equal Opportunity
Colorado State University, Fort Collins, CO 80523 USA