简体   繁体   中英

Quick sort implementation in C

To answer everyone's first question: Yes, this is for school. That being said, I feel like I'm pretty close to getting this to work, at least partially. Seems to sort most of the data, but I can't see any pattern to what is not being sorted.

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

void quicksort(int *values, int size);
void printout(int[], int size);

void main(){
    printf("starting");
    int size=20;
    int values[size];
    int i;
    for (i=0;i<size;i++){
        values[i]=(rand()%113);
    }
    printf("\nBefore Sort:\n");
    printout(values,size);
    quicksort(values, size);
    printf("\nAfter Sort:\n");
    printout(values,size);
}

void printout(int values[],int size){
    int i;
    for (i=0;i<size;i++){
        if (i % 20 == 0){
            printf("\n");
        }
        printf("%3i ", values[i]);
    }
}

void quicksort(int *values, int size){
    if (size < 2){
        return;
    }
    int pivot=values[size];
    int left[size];
    int right[size];
    int center[size];
    int i,lc,rc,cc;  //counters for left, right and center arrays
    lc=rc=cc=0; //initially 0

    for (i=0; i<size-1; i++){
        if (values[i] < pivot){
            left[lc]=values[i];
            lc++;
        }
        else if (values[i] > pivot){
            right[rc]=values[i];
            rc++;
        }
        else{
            center[cc]=values[i];
            cc++;
        }
    }
    quicksort(left, lc);
    quicksort(right, rc);
    int lc2,rc2,cc2;
    lc2=rc2=cc2=0;  //note the first variable is lowercase L, not 1
    while (lc2+cc2+rc2 < size-1){  // here we recombine our arrays
        while (lc2 < lc){
            values[lc2+rc2+cc2] = left[lc2];
            lc2+=1;
        }
        while (cc2 < cc){
            values[lc2+rc2+cc2] = center[cc2];
            cc2+=1;
        }
        while (rc2 < rc){
            values[lc2+rc2+cc2] = right[rc2];
            rc2+=1;
        }
    }

}

My output for this is as follows:

Before Sort:

41 48 6 58 72 17 65 91 68 56 55 8 3 103 17 39 57 77 81 12

After Sort:

6 8 17 41 48 58 72 65 68 56 55 3 17 39 91 57 77 103 81 12

It's definitely doing something... Anybody have any ideas as to what the heck I'm missing here?

You're choosing the pivot wrong - values[size] lies outside of the range. If you want to use the last element, use values[size - 1] .

I've included tips on debugging that you can apply in the future to find problems like these.

Problem 1

int pivot=values[size];

size is past the end of the range being sorted. At the top level when the range is the entire array that means it's outside the array. And at the other levels it's either outside the array or the pivot value is from a different range.

Discovering this defect may require either careful code review or a tool designed to catch this sort of error such as is built into some compilers.

A more difficult method involves inspecting the runtime behavior, either with print statements or a debugger, and recognizing that the first pivot is not a value in the array. Testing with known input instead of random input helps with this method because it makes it more likely that you'll notice anything unexpected.


Problem 2

You also do not move the pivot into the correct location.

One technique for discovering this would be to check post-conditions. For example at the end of quicksort() the range should be sorted. So if you insert printout(values,size); at the end of that function then might notice in a few short cases where just the last element is out of order. Additional print statements can help you trace what's causing this.


Problem 3

main() must return int , not void .

Using a stricter compiler will catch this for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM