Problem: Finding the Two Largest Elements of an Array

Problem

We want to implement a function called find_two_largest_elements.

This function has a return type of void and takes as input the following parameters:

  • An array a of type double with the values to operate on;
  • An integer n containing the number of elements in the array;
  • A pointer to a double that will contain the first largest element of the array: max1;
  • A pointer to a double that will contain the second largest element of the array: max2.

The function signature will be:

void find_two_largest_elements(double a[], int n, double *max1, double *max2);

Implementation

Let's try to implement the function.

From the requirements described above, the function uses two pointers to return the results of maximum and second maximum of the array. Furthermore, the function must be able to find the two largest elements even if they are equal. For example, if the array is [1, 2, 3, 3] then the maximum will be 3 and the second maximum will be 3. If the array is [1, 2, 3, 4] then the maximum will be 4 and the second maximum will be 3.

A possible implementation is the following:

void find_two_largest_elements(double a[], int n, double *max1, double *max2) {
    int i;

    /* Initialize the maximum to the first element of the array */
    *max1 = a[0];

    /* Initialize the second maximum to the second element of the array */
    *max2 = a[1];

    /* If the second maximum is greater than the maximum, swap the two values */
    if (*max2 > *max1) {
        double tmp = *max1;
        *max1 = *max2;
        *max2 = tmp;
    }

    for (i = 2; i < n; ++i) {
        if (a[i] > *max1) {
            *max2 = *max1;
            *max1 = a[i];
        } else if (a[i] > *max2) {
            *max2 = a[i];
        }
    }
}

Note that we have optimized the implementation as the maximum and second maximum are calculated in a single loop.

A possible problem in this implementation is that if the array contains fewer than two elements, the program might not work correctly. For example, if the array contains only one element, then the maximum will be a[0] and the second maximum will be a[1] which however does not exist. To solve this problem, we can add an initial check to verify that the array has at least two elements:

void find_two_largest_elements(double a[], int n, double *max1, double *max2) {
    int i;

    /* If the array contains fewer than two elements, do nothing */
    if (n < 2) {
        return;
    }

    /* Initialize the maximum to the first element of the array */
    *max1 = a[0];

    /* Initialize the second maximum to the second element of the array */
    *max2 = a[1];

    /* If the second maximum is greater than the maximum, swap the two values */
    if (*max2 > *max1) {
        double tmp = *max1;
        *max1 = *max2;
        *max2 = tmp;
    }

    for (i = 2; i < n; ++i) {
        if (a[i] > *max1) {
            *max2 = *max1;
            *max1 = a[i];
        } else if (a[i] > *max2) {
            *max2 = a[i];
        }
    }
}

Complete Program

Let's now try to write a program that uses the find_two_largest_elements function to find the two largest elements of an array of 10 elements.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <stdio.h>

void find_two_largest_elements(double a[], int n, double *max1, double *max2);

int main() {
    const int N = 10;
    double max1, max2;
    double a[N];
    int i;

    /* Initialize the array by reading values from keyboard */
    printf("Enter 10 values: ");

    for (i = 0; i < N; ++i) {
        scanf("%lf", &a[i]);
    }

    /* Find the two largest elements */
    find_two_largest_elements(a, 10, &max1, &max2);

    /* Print the results */
    printf("The maximum is %f\n", max1);
    printf("The second maximum is %f\n", max2);

    return 0;
}

void find_two_largest_elements(double a[], int n, double *max1, double *max2) {
    int i;

    /* If the array contains fewer than two elements, do nothing */
    if (n < 2) {
        return;
    }

    /* Initialize the maximum to the first element of the array */
    *max1 = a[0];

    /* Initialize the second maximum to the second element of the array */
    *max2 = a[1];

    /* If the second maximum is greater than the maximum, swap the two values */
    if (*max2 > *max1) {
        double tmp = *max1;
        *max1 = *max2;
        *max2 = tmp;
    }

    for (i = 2; i < n; ++i) {
        if (a[i] > *max1) {
            *max2 = *max1;
            *max1 = a[i];
        } else if (a[i] > *max2) {
            *max2 = a[i];
        }
    }
}