Implementando upper_bound() y lower_bound() en C

Dada una array ordenada arr[] de N enteros y un número K , la tarea es escribir el programa C para encontrar el límite superior() y el límite inferior() de K en la array dada.
Ejemplos: 
 

Entrada: arr[] = {4, 6, 10, 12, 18, 20}, K = 6 
Salida: El 
límite inferior de 6 es 6 en el índice 1 
El límite superior de 6 es 10 en el índice 2
Entrada: arr[] = { 4, 6, 10, 12, 18, 20}, K = 20 
Salida: 
el límite inferior de 20 es 20 en el índice 5 
El límite superior no existe 
 

Enfoque: La idea es utilizar Binary Search . A continuación se muestran los pasos: 
 

  • Para límite_inferior(): 
    1. Inicialice startIndex como 0 y endIndex como N – 1 .
    2. Compare K con el elemento medio (digamos arr[mid] ) de la array.
    3. Si el elemento medio es mayor que K , entonces actualice endIndex como un índice medio ( mid ).
    4. De lo contrario, actualice startIndex como mid + 1.
    5. Repita los pasos anteriores hasta que startIndex sea menor que endIndex .
    6. Después de todos los pasos anteriores, startIndex es el límite inferior de K en la array dada.
  • Para límite_superior(): 
    1. Inicialice startIndex como 0 y endIndex como N – 1 .
    2. Compare K con el elemento medio (digamos arr[mid] ) de la array.
    3. Si el elemento del medio es menor que igual a K , actualice startIndex como índice medio + 1 ( medio + 1).
    4. De lo contrario, actualice endIndex como mid.
    5. Repita los pasos anteriores hasta que startIndex sea menor que endIndex .
    6. Después de todos los pasos anteriores, startIndex es el límite superior de K en la array dada.

A continuación se muestra la implementación iterativa y recursiva del enfoque anterior:
 

Iterative Solution

// C program for iterative implementation
// of the above approach
 
#include <stdio.h>
 
// Function to implement lower_bound
int lower_bound(int arr[], int N, int X)
{
    int mid;
 
    // Initialise starting index and
    // ending index
    int low = 0;
    int high = N;
 
    // Till low is less than high
    while (low < high) {
        mid = low + (high - low) / 2;
 
        // If X is less than or equal
        // to arr[mid], then find in
        // left subarray
        if (X <= arr[mid]) {
            high = mid;
        }
 
        // If X is greater arr[mid]
        // then find in right subarray
        else {
            low = mid + 1;
        }
    }
   
    // if X is greater than arr[n-1]
    if(low < N && arr[low] < X) {
       low++;
    }
       
    // Return the lower_bound index
    return low;
}
 
// Function to implement upper_bound
int upper_bound(int arr[], int N, int X)
{
    int mid;
 
    // Initialise starting index and
    // ending index
    int low = 0;
    int high = N;
 
    // Till low is less than high
    while (low < high) {
        // Find the middle index
        mid = low + (high - low) / 2;
 
        // If X is greater than or equal
        // to arr[mid] then find
        // in right subarray
        if (X >= arr[mid]) {
            low = mid + 1;
        }
 
        // If X is less than arr[mid]
        // then find in left subarray
        else {
            high = mid;
        }
    }
   
    // if X is greater than arr[n-1]
    if(low < N && arr[low] <= X) {
       low++;
    }
 
    // Return the upper_bound index
    return low;
}
 
// Function to implement lower_bound
// and upper_bound of X
void printBound(int arr[], int N, int X)
{
    int idx;
 
    // If lower_bound doesn't exists
    if (lower_bound(arr, N, X) == N) {
        printf("Lower bound doesn't exist");
    }
    else {
 
        // Find lower_bound
        idx = lower_bound(arr, N, X);
        printf("Lower bound of %d is"
               "% d at index % d\n ",
               X,
               arr[idx], idx);
    }
 
    // If upper_bound doesn't exists
    if (upper_bound(arr, N, X) == N) {
        printf("Upper bound doesn't exist");
    }
    else {
 
        // Find upper_bound
        idx = upper_bound(arr, N, X);
        printf("Upper bound of %d is"
               "% d at index % d\n ",
               X,
               arr[idx], idx);
    }
}
 
// Driver Code
int main()
{
    // Given array
    int arr[] = { 4, 6, 10, 12, 18, 20 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Element whose lower bound and
    // upper bound to be found
    int X = 6;
 
    // Function Call
    printBound(arr, N, X);
    return 0;
}

Recursive Solution

// C program for recursive implementation
// of the above approach
 
#include <stdio.h>
 
// Recursive implementation of
// lower_bound
int lower_bound(int arr[], int low,
                int high, int X)
{
 
    // Base Case
    if (low > high) {
        return low;
    }
 
    // Find the middle index
    int mid = low + (high - low) / 2;
 
    // If arr[mid] is greater than
    // or equal to X then search
    // in left subarray
    if (arr[mid] >= X) {
        return lower_bound(arr, low,
                           mid - 1, X);
    }
 
    // If arr[mid] is less than X
    // then search in right subarray
    return lower_bound(arr, mid + 1,
                       high, X);
}
 
// Recursive implementation of
// upper_bound
int upper_bound(int arr[], int low,
                int high, int X)
{
 
    // Base Case
    if (low > high)
        return low;
 
    // Find the middle index
    int mid = low + (high - low) / 2;
 
    // If arr[mid] is less than
    // or equal to X search in
    // right subarray
    if (arr[mid] <= X) {
        return upper_bound(arr, mid + 1,
                           high, X);
    }
 
    // If arr[mid] is greater than X
    // then search in left subarray
    return upper_bound(arr, low,
                       mid - 1, X);
}
 
// Function to implement lower_bound
// and upper_bound of X
void printBound(int arr[], int N, int X)
{
    int idx;
 
    // If lower_bound doesn't exists
    if (lower_bound(arr, 0, N, X) == N) {
        printf("Lower bound doesn't exist");
    }
    else {
 
        // Find lower_bound
        idx = lower_bound(arr, 0, N, X);
        printf("Lower bound of %d "
               "is %d at index %d\n",
               X, arr[idx], idx);
    }
 
    // If upper_bound doesn't exists
    if (upper_bound(arr, 0, N, X) == N) {
        printf("Upper bound doesn't exist");
    }
    else {
 
        // Find upper_bound
        idx = upper_bound(arr, 0, N, X);
        printf("Upper bound of %d is"
               "% d at index % d\n ",
               X,
               arr[idx], idx);
    }
}
 
// Driver Code
int main()
{
    // Given array
    int arr[] = { 4, 6, 10, 12, 18, 20 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Element whose lower bound and
    // upper bound to be found
    int X = 6;
 
    // Function Call
    printBound(arr, N, X);
    return 0;
}
Producción: 

Lower bound of 6 is 6 at index  1
 Upper bound of 6 is 10 at index  2

 

Complejidad de tiempo: O (log 2 N), donde N es el número de elementos en la array.
 Espacio Auxiliar: O(1).

Publicación traducida automáticamente

Artículo escrito por saurabhshadow y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *