COMP1511 17s1 Code Examples from Lectures on sorting_and_searching Introduction to Programming

Instrument linear search and binary search with an operation counter and compare their performance on a sorted arrays of random numbers.

Array size is specified as a command line argument

$ ./a.out 1000000

Array size is 1000000, elements are: 3 10 14 6 26 49 61 69 72 73 105 130 36 137 141 58 150 184 197 159 209 ...

Search for? 49

Linear search: 49 is in the numbers - search took 6 operations

Binary search: 49 is in the numbers - search took 20 operations

Search for? 42

Linear search: 42 is not in the numbers - search took 1000000 operations

Binary search: 42 is not in the numbers - search took 20 operations

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

int linear_search(int array[], int length, int x);
int binary_search(int array[], int length, int x);
void quicksort(int array[], int length);
void quicksort1(int array[], int lo, int hi);
int partition(int array[], int lo, int hi);
void random_ints(int array[], int length);

int operation_counter;

int main(int argc, char *argv[]) {
    int *numbers;
    int i, length, x;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <array-size>\n", argv[0]);
        exit(1);
    }
    length = atoi(argv[1]);

    // use malloc to create an array so we can
    // because we may want an array too large to be a global variable

    numbers = malloc(length * sizeof (int));
    if (numbers == NULL) {
        perror("");
        exit(1);
    }

    random_ints(numbers, length);
    quicksort(numbers, length);

    printf("Array size is %d, elements are: ", length);

    for (i = 0; i < length; i = i + 1) {
        printf(" %d", numbers[i]);
        if (i == 20) {
            printf(" ... ");
            i = length;
        }
    }
    printf("\n");

    while (1) {
        printf("Search for? ");
        if (scanf("%d", &x) != 1) {
            free(numbers);
            return 0;
        }

        operation_counter = 0;
        printf("\nLinear search: ");
        if (linear_search(numbers, length, x) == 1) {
            printf("%d is in the numbers", x);
        } else {
            printf("%d is not in the numbers", x);
        }
        printf(" - search took %d operations\n", operation_counter);

        operation_counter = 0;
        printf("Binary search: ");
        if (binary_search(numbers, length, x) == 1) {
            printf("%d is in the numbers", x);
        } else {
            printf("%d is not in the numbers", x);
        }
        printf(" - search took %d operations\n\n", operation_counter);
    }
}

int linear_search(int array[], int length, int x) {
    int i;
    for (i = 0; i < length; i = i + 1) {
        operation_counter++;
        if (array[i] == x) {
            return 1;
        }
    }
    return 0;
}

int binary_search(int array[], int length, int x) {
    int lower = 0;
    int upper = length - 1;
    while (lower <= upper) {
        int mid = (lower + upper)/ 2;
        operation_counter++;
        if (array[mid] == x) {
            return 1;
        } else if (array[mid] > x) {
            upper = mid - 1;
        } else {
            lower = mid + 1;
        }
    }
    return 0;
}

void random_ints(int array[], int length) {
     for (int i = 0; i < length; i = i + 1) {
        array[i] = rand() % (10 * length);
    }
}


void sorted_random_ints(int array[], int length) {
    random_ints(array, length);
}

void quicksort(int array[], int length) {
    quicksort1(array, 0, length - 1);
}

void quicksort1(int array[], int lo, int hi) {
    if (lo >= hi) {
        return;
    }
    int p = partition(array, lo, hi);
    quicksort1(array, lo, p - 1);
    quicksort1(array, p + 1, hi);
}


int partition(int array[], int lo, int hi) {
    int i = lo;
    int j = hi;

    // use middle value as pivot
    int pivotValue = array[(lo + hi) / 2];

    // start from left and right ends
    while (i < j) {
        // Find two out-of-place elements
        while (array[i] < pivotValue) {
            i = i + 1;
            operation_counter++;
        }
        while (array[j] > pivotValue) {
            j = j - 1;
            operation_counter++;
        }
        // and swap them over
        if (i < j) {
            int temp = array[i];
            array[i] = array[j];
            array[j] = temp;
            i = i + 1;
            j = j - 1;
        }
    }
    return j;
}

Instrument quicksort and bubblesort with an operation counter and compare performance on arrays of random numbers of size 10..10000

$ dcc compare_sorts.c
$ ./a.out

Array size 10: bubblesort took 81 operations, quicksort took 24 operations

Array size 100: bubblesort took 8415 operations, quicksort took 457 operations

Array size 1000: bubblesort took 981018 operations, quicksort took 9351 operations

Array size 10000: bubblesort took 98790120 operations, quicksort took 102807 operations

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

// use a global variable to count operations
// at key points for both sorting algorithms
int operation_counter;

void bubblesort(int array[], int length);
void quicksort(int array[], int length);
void quicksort1(int array[], int lo, int hi);
int partition(int array[], int lo, int hi);
void random_ints(int array[], int length);

int main(void) {
    for (int n = 10; n <= 10000; n = n * 10) {
        int numbers1[n];
        int numbers2[n];

        random_ints(numbers1, n);
        for (int i = 0; i < n; i = i + 1) {
            numbers2[i] = numbers1[i];
        }

        printf("Array size %5d: ", n);
        operation_counter = 0;
        bubblesort(numbers1, n);
        printf(" bubblesort took %8d operations,", operation_counter);
        operation_counter = 0;
        quicksort(numbers2, n);
        printf("  quicksort took %6d operations\n", operation_counter);

        for (int i = 0; i < n; i = i + 1) {
            if(numbers2[i] != numbers1[i]) {
                printf("arrays differ at index %d\n", i);
                return 1;
            }
        }
    }
    return 0;
}

// https://en.wikipedia.org/wiki/Bubble_sort

void bubblesort(int array[], int length) {
    int swapped = 1;
    while (swapped) {
        swapped = 0;
        for (int i = 1; i < length; i = i + 1) {
            operation_counter++;
            if (array[i] < array[i - 1]) {
                int tmp = array[i];
                array[i] = array[i - 1];
                array[i - 1] = tmp;
                swapped = 1;
            }
        }
    }
}

// https://en.wikipedia.org/wiki/Quicksort

void quicksort(int array[], int length) {
    quicksort1(array, 0, length - 1);
}

void quicksort1(int array[], int lo, int hi) {
    if (lo >= hi) {
        return;
    }
    // rearrange array so that
    // all elements smaller than pivot value are below it and
    // all element larger than pivot value are above it
    int p = partition(array, lo, hi);
    // sort lower part of array
    quicksort1(array, lo, p);

    // sort upper part of array
    quicksort1(array, p + 1, hi);
}


int partition(int array[], int lo, int hi) {
    int i = lo;
    int j = hi;

    // use middle value as pivot
    int pivotValue = array[(lo + hi) / 2];

    // start from left and right ends
    while (1) {

        // Look for pair to swap

        while (array[i] < pivotValue) {
            i = i + 1;
            operation_counter++;
        }

        while (array[j] > pivotValue) {
            j = j - 1;
            operation_counter++;
        }

        // No pair to swap so return
        if (i >= j) {
            return j;
        }
        // and swap them over
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
        i = i + 1;
        j = j - 1;
    }
}

void random_ints(int array[], int length) {
     for (int i = 0; i < length; i = i + 1) {
        array[i] = rand() % (10 * length);
    }
}