Open In App

Convex Hull Algorithm in C

Last Updated : 18 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

The Convex Hull problem is a fundamental computational geometry problem, where the goal is to find the smallest convex polygon called convex hull that can enclose a set of points in a 2D plane. This problem has various applications, such as in computer graphics, geographic information systems, and collision detection.

In this article, we will learn multiple algorithms for solving the Convex Hull problem and their implementation in the C programming language.

Example

Input:
Point points[] = {{0, 0}, {0, 4}, {-4, 0}, {5, 0}, {0, -6}, {1, 0}};

Output:
The points in the Convex Hull are:
(-4, 0)
(5, 0)
(0, -6)
(0, 4)

What is Convex Hull?

The convex hull of a set of points in a Euclidean space is the smallest convex polygon that encloses all the points. In 2D space, the convex hull is a convex polygon. If we imagine each point as a nail sticking out of a board, the convex hull is the shape formed by stretching a rubber band around the nails.

Convex-Hull
Convex Hull

Convex Hull using Divide and Conquer Algorithm in C

In this approach, we recursively divide the set of points into smaller subsets, finds the convex hulls for these subsets, and then merges the results to form the final convex hull. This is similar to the merge sort algorithm in terms of its approach.

Approach:

  • Start dividing the set of points into two halves based on their x-coordinates. The left half will contain all points with x-coordinates less than or equal to the median x-coordinate, and the right half will contain the remaining points.
  • Recursively apply the divide and conquer approach to find the convex hull for the left half and the right half.
  • After finding the convex hulls for the left and right halves, the next step is to merge these two convex hulls. To do this, find the upper and lower tangents that connect the two convex hulls.
    • The upper tangent is the line that touches both convex hulls and lies above all the points in both hulls.
    • The lower tangent is the line that touches both convex hulls and lies below all the points in both hulls.
    • The points between these tangents form the final convex hull.
  • Finally, Combine the points from the left convex hull and right convex hull that lie between the tangents to form the complete convex hull for the entire set of points.
Final-Convex-Hull

Below is the implementation of above approach:

C
// C program for Convex Hull using Divide and Conquer Algorithm

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

// Structure to represent a point
typedef struct
{
    int first;
    int second;
} Pair;

// Global variable to store the center of the polygon
Pair mid;

// Function to determine the quadrant of a point
int quad(Pair p)
{
    if (p.first >= 0 && p.second >= 0)
        return 1;
    if (p.first <= 0 && p.second >= 0)
        return 2;
    if (p.first <= 0 && p.second <= 0)
        return 3;
    return 4;
}

// Function to check the orientation of three points
int orientation(Pair a, Pair b, Pair c)
{
    int res = (b.second - a.second) * (c.first - b.first) - (c.second - b.second) * (b.first - a.first);

    if (res == 0)
        return 0;
    if (res > 0)
        return 1;
    return -1;
}

// Compare function for sorting
int compare(const void *p1, const void *q1)
{
    Pair *p = (Pair *)p1;
    Pair *q = (Pair *)q1;

    Pair p_diff = {p->first - mid.first, p->second - mid.second};
    Pair q_diff = {q->first - mid.first, q->second - mid.second};

    int one = quad(p_diff);
    int two = quad(q_diff);

    if (one != two)
        return (one < two) ? -1 : 1;

    return (p_diff.second * q_diff.first < q_diff.second * p_diff.first) ? -1 : 1;
}

// Function to merge two convex hulls
Pair *merger(Pair *a, int n1, Pair *b, int n2, int *ret_size)
{
    int ia = 0, ib = 0;
    for (int i = 1; i < n1; i++)
        if (a[i].first > a[ia].first)
            ia = i;

    for (int i = 1; i < n2; i++)
        if (b[i].first < b[ib].first)
            ib = i;

    int inda = ia, indb = ib;
    int done = 0;
    while (!done)
    {
        done = 1;
        while (orientation(b[indb], a[inda], a[(inda + 1) % n1]) >= 0)
            inda = (inda + 1) % n1;

        while (orientation(a[inda], b[indb], b[(n2 + indb - 1) % n2]) <= 0)
        {
            indb = (n2 + indb - 1) % n2;
            done = 0;
        }
    }

    int uppera = inda, upperb = indb;
    inda = ia;
    indb = ib;
    done = 0;
    while (!done)
    {
        done = 1;
        while (orientation(a[inda], b[indb], b[(indb + 1) % n2]) >= 0)
            indb = (indb + 1) % n2;

        while (orientation(b[indb], a[inda], a[(n1 + inda - 1) % n1]) <= 0)
        {
            inda = (n1 + inda - 1) % n1;
            done = 0;
        }
    }

    int lowera = inda, lowerb = indb;
    Pair *ret = (Pair *)malloc((n1 + n2) * sizeof(Pair));
    int ind = uppera;
    int k = 0;

    ret[k++] = a[uppera];
    while (ind != lowera)
    {
        ind = (ind + 1) % n1;
        ret[k++] = a[ind];
    }

    ind = lowerb;
    ret[k++] = b[lowerb];
    while (ind != upperb)
    {
        ind = (ind + 1) % n2;
        ret[k++] = b[ind];
    }

    *ret_size = k;
    return ret;
}

// Brute force algorithm to find the convex hull for a small set of points
Pair *bruteHull(Pair *a, int n, int *ret_size)
{
    int max_combinations = n * (n - 1) / 2;
    Pair *ret = (Pair *)malloc(n * sizeof(Pair));
    int k = 0;

    for (int i = 0; i < n; i++)
    {
        for (int j = i + 1; j < n; j++)
        {
            int x1 = a[i].first, x2 = a[j].first;
            int y1 = a[i].second, y2 = a[j].second;

            int a1 = y1 - y2;
            int b1 = x2 - x1;
            int c1 = x1 * y2 - y1 * x2;
            int pos = 0, neg = 0;

            for (int m = 0; m < n; m++)
            {
                if (a1 * a[m].first + b1 * a[m].second + c1 <= 0)
                    neg++;
                if (a1 * a[m].first + b1 * a[m].second + c1 >= 0)
                    pos++;
            }

            if (pos == n || neg == n)
            {
                int already_added = 0;
                for (int l = 0; l < k; l++)
                {
                    if (ret[l].first == a[i].first && ret[l].second == a[i].second)
                        already_added = 1;
                }
                if (!already_added)
                    ret[k++] = a[i];

                already_added = 0;
                for (int l = 0; l < k; l++)
                {
                    if (ret[l].first == a[j].first && ret[l].second == a[j].second)
                        already_added = 1;
                }
                if (!already_added)
                    ret[k++] = a[j];
            }
        }
    }

    *ret_size = k;
    ret = (Pair *)realloc(ret, k * sizeof(Pair));

    mid.first = 0;
    mid.second = 0;
    for (int i = 0; i < k; i++)
    {
        mid.first += ret[i].first;
        mid.second += ret[i].second;
        ret[i].first *= k;
        ret[i].second *= k;
    }

    qsort(ret, k, sizeof(Pair), compare);

    for (int i = 0; i < k; i++)
    {
        ret[i].first /= k;
        ret[i].second /= k;
    }

    return ret;
}

// Function to divide the set of points and recursively find the convex hull
Pair *divide(Pair *a, int n, int *ret_size)
{
    if (n <= 5)
        return bruteHull(a, n, ret_size);

    int mid = n / 2;
    Pair *left_hull;
    Pair *right_hull;
    int left_size, right_size;

    left_hull = divide(a, mid, &left_size);
    right_hull = divide(a + mid, n - mid, &right_size);

    return merger(left_hull, left_size, right_hull, right_size, ret_size);
}

// Driver code
int main()
{
    Pair a[] = {{0, 0},   {1, -4},  {-1, -5}, {-5, -3}, {-3, -1},
                {-1, -3}, {-2, -2}, {-1, -1}, {-2, -1}, {-1, 1}};
    int n = sizeof(a) / sizeof(a[0]);

    qsort(a, n, sizeof(Pair), compare);
    int ret_size;
    Pair *ans = divide(a, n, &ret_size);

    printf("Convex hull:\n");
    for (int i = 0; i < ret_size; i++)
    {
        printf("%d %d\n", ans[i].first, ans[i].second);
    }

    free(ans);
    return 0;
}

Output
Convex hull:
0 0
-1 1
-3 -1
-5 -3
-1 -5
1 -4

Time Complexity: The merging of the left and the right convex hulls take O(n) time and as we are dividing the points into two equal parts, so the time complexity of the above algorithm is O(n * log n). 
Auxiliary Space: O(n)

Convex Hull using Jarvis’ March (Wrapping) in C

Jarvis's March, also known as the Gift Wrapping algorithm, is a straightforward method that works by "wrapping" the points in a counterclockwise manner. It starts from the leftmost point and selects the next point in the convex hull by choosing the most counterclockwise point relative to the current point.

Approach:

  • Start identifying the leftmost point in the set of points.
  • Starting from the leftmost point, select the next point in the convex hull by checking the orientation of the triplet formed by the current point, a candidate point, and any other point in the set.
  • The candidate point that forms the most counterclockwise angle relative to the current point and the next point in the sequence is selected.
  • Add the selected point to the convex hull and move on to it as the new "current" point.
  • Continue this process until you return to the starting point.
  • Stop when the convex hull is fully constructed, and all the points on the hull have been identified.
Convex-Hull-using-Jarvis-Algorithm-or-Wrapping

Below is the implementation of above approach:

C
// C program to implement Convex Hull using Jarvis’ March (Wrapping)
#include <stdio.h>

// Define the Point structure
struct Point
{
    int x, y;
};

// To find the orientation of ordered triplet (p, q, r).
// The function returns the following values:
// 0 --> p, q, and r are collinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(struct Point p, struct Point q, struct Point r)
{
    int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);

    if (val == 0)
        return 0;             // collinear
    return (val > 0) ? 1 : 2; // clock or counterclockwise
}

// Prints convex hull of a set of n points.
void convexHull(struct Point points[], int n)
{
    // There must be at least 3 points
    if (n < 3)
        return;

    // Initialize Result
    struct Point hull[n];
    int hull_size = 0;

    // Find the leftmost point
    int l = 0;
    for (int i = 1; i < n; i++)
    {
        if (points[i].x < points[l].x)
        {
            l = i;
        }
    }

    // Start from leftmost point, keep moving counterclockwise
    // until we reach the start point again. This loop runs O(h)
    // times where h is the number of points in the result or output.
    int p = l, q;
    do
    {
        // Add current point to result
        hull[hull_size++] = points[p];

        // Search for a point 'q' such that orientation(p, q, x)
        // is counterclockwise for all points 'x'.
        q = (p + 1) % n;
        for (int i = 0; i < n; i++)
        {
            // If i is more counterclockwise than current q, then update q
            if (orientation(points[p], points[i], points[q]) == 2)
            {
                q = i;
            }
        }

        // Now q is the most counterclockwise with respect to p
        // Set p as q for the next iteration, so that q is added to
        // result 'hull'
        p = q;

    }

    // While we don't come to the first point
    while (p != l);

    // Print Result
    for (int i = 0; i < hull_size; i++)
    {
        printf("(%d, %d)\n", hull[i].x, hull[i].y);
    }
}

// Driver program to test the above functions
int main()
{
    struct Point points[] = {{0, 3}, {2, 2}, {1, 1}, {2, 1}, {3, 0}, {0, 0}, {3, 3}};
    int n = sizeof(points) / sizeof(points[0]);
    convexHull(points, n);
    return 0;
}

Output
(0, 3)
(0, 0)
(3, 0)
(3, 3)

Time Complexity: O(m * n), where n is number of input points and m is number of output or hull points (m <= n).  For every point on the hull we examine all the other points to determine the next point.
Worst case, Time complexity: O(n2).  The worst case occurs when all the points are on the hull (m = n).
Auxiliary Space: O(n), since n extra space has been taken.

Convex Hull using Graham Scan in C

Graham Scan is a more efficient algorithm compared to Jarvis's March. It works by first sorting the points based on their polar angles relative to a reference point (typically the point with the lowest y-coordinate) and then processing the points to construct the convex hull.

Approach:

  • Find the point with the lowest y-coordinate. This point will serve as the reference point for sorting the other points based on their polar angles.
  • Sort all the points based on the polar angle they make with the reference point. If two points have the same angle, the one closer to the reference point is considered first.
  • Start constructing the convex hull by considering the first three sorted points. These points are always part of the convex hull.
  • Traverse the sorted points one by one. For each point, check the orientation formed by the last two points on the convex hull and the current point.
  • If the orientation is counterclockwise, the current point is part of the convex hull. If not, remove the last point from the hull (since it would create a concave shape) and continue checking with the previous points until a counterclockwise orientation is achieved.
  • Continue adding points until all points have been processed. Finally, the result is the convex hull that encloses all the given points.

Below is the implementation of above approach

C
// C program to implement Convex Hull using Graham Scan
#include <stdio.h>
#include <stdlib.h>

// Define the Point structure
struct Point
{
    int x, y;
};

// Global point needed for sorting points with reference to the first point
struct Point p0;

// A utility function to find the next-to-top element in a stack
struct Point nextToTop(struct Point *stack, int *top)
{
    struct Point p = stack[*top];
    (*top)--;
    struct Point res = stack[*top];
    (*top)++;
    return res;
}

// A utility function to swap two points
void swap(struct Point *p1, struct Point *p2)
{
    struct Point temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}

// A utility function to return the square of the distance between p1 and p2
int distSq(struct Point p1, struct Point p2)
{
    return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
}

// To find the orientation of ordered triplet (p, q, r).
// The function returns the following values:
// 0 --> p, q, and r are collinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(struct Point p, struct Point q, struct Point r)
{
    int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);

    if (val == 0)
        return 0;             // collinear
    return (val > 0) ? 1 : 2; // clock or counterclockwise
}

// A function used by qsort() to sort an array of points with respect to the first point
int compare(const void *vp1, const void *vp2)
{
    struct Point *p1 = (struct Point *)vp1;
    struct Point *p2 = (struct Point *)vp2;

    int o = orientation(p0, *p1, *p2);
    if (o == 0)
        return (distSq(p0, *p2) >= distSq(p0, *p1)) ? -1 : 1;

    return (o == 2) ? -1 : 1;
}

// Prints convex hull of a set of n points.
void convexHull(struct Point points[], int n)
{
    int ymin = points[0].y, min = 0;
    for (int i = 1; i < n; i++)
    {
        int y = points[i].y;
        if ((y < ymin) || (ymin == y && points[i].x < points[min].x))
            ymin = points[i].y, min = i;
    }

    swap(&points[0], &points[min]);

    p0 = points[0];
    qsort(&points[1], n - 1, sizeof(struct Point), compare);

    int m = 1;
    for (int i = 1; i < n; i++)
    {
        while (i < n - 1 && orientation(p0, points[i], points[i + 1]) == 0)
            i++;
        points[m] = points[i];
        m++;
    }

    if (m < 3)
        return;

    struct Point *stack = (struct Point *)malloc(m * sizeof(struct Point));
    int top = -1;

    stack[++top] = points[0];
    stack[++top] = points[1];
    stack[++top] = points[2];

    for (int i = 3; i < m; i++)
    {
        while (top > 0 && orientation(nextToTop(stack, &top), stack[top], points[i]) != 2)
            top--;
        stack[++top] = points[i];
    }

    while (top >= 0)
    {
        struct Point p = stack[top--];
        printf("(%d, %d)\n", p.x, p.y);
    }

    free(stack);
}

// Driver program to test above functions
int main()
{
    struct Point points[] = {{0, 3}, {1, 1}, {2, 2}, {4, 4}, {0, 0}, {1, 2}, {3, 1}, {3, 3}};
    int n = sizeof(points) / sizeof(points[0]);
    convexHull(points, n);
    return 0;
}

Output
(0, 3)
(4, 4)
(3, 1)
(0, 0)

Time Complexity: O(nLogn), where n be the number of input points.
The first step (finding the bottom-most point) takes O(n) time. The second step (sorting points) takes O(nLogn) time. The third step takes O(n) time. In the third step, every element is pushed and popped at most one time. So the sixth step to process points one by one takes O(n) time, assuming that the stack operations take O(1) time. Overall complexity is O(n) + O(nLogn) + O(n) + O(n) which is O(nLogn).
Auxiliary Space: O(n), as explicit stack is used, since no extra space has been taken.

Convex Hull using Monotone Chain Algorithm in C

The Monotone Chain algorithm constructs the convex hull in O(N log N) time by first sorting the points and then constructing the upper and lower hulls separately. This algorithm is also known as Andrew's algorithm.

Approach:

  • Start by sorting the points based on their x-coordinates. If two points have the same x-coordinate, sort them by their y-coordinates.
  • Construct the Lower Hull:
    • Begin with the leftmost point and proceed to the rightmost point. For each point, check if the last two points in the current hull and the current point form a clockwise turn. If they do, remove the second-to-last point from the hull.
    • Add the current point to the lower hull.
  • Construct the Upper Hull:
    • After constructing the lower hull, repeat the process for the upper hull but traverse the points from right to left.
  • Combine the upper and lower hulls. The points where the upper and lower hulls meet are only included once.

Below is the implementation of above approach:

C
// C program to Convex Hull using Monotone Chain Algorithm
#include <stdio.h>
#include <stdlib.h>

#define llu long long int

struct Point
{
    llu x, y;
};

// Comparison function to sort points lexicographically
int compare(const void *a, const void *b)
{
    struct Point *p1 = (struct Point *)a;
    struct Point *p2 = (struct Point *)b;
    if (p1->x != p2->x)
        return (p1->x < p2->x) ? -1 : 1;
    return (p1->y < p2->y) ? -1 : 1;
}

// Cross product of two vectors OA and OB
// returns positive for counterclockwise
// turn and negative for clockwise turn
llu cross_product(struct Point O, struct Point A, struct Point B)
{
    return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x);
}

// Returns a list of points on the convex hull in counterclockwise order
struct Point *convex_hull(struct Point *A, int n, int *hull_size)
{
    if (n <= 3)
    {
        *hull_size = n;
        return A;
    }

    struct Point *ans = (struct Point *)malloc(2 * n * sizeof(struct Point));
    int k = 0;

    // Sort points lexicographically
    qsort(A, n, sizeof(struct Point), compare);

    // Build lower hull
    for (int i = 0; i < n; ++i)
    {
        while (k >= 2 && cross_product(ans[k - 2], ans[k - 1], A[i]) <= 0)
            k--;
        ans[k++] = A[i];
    }

    // Build upper hull
    for (int i = n - 1, t = k + 1; i > 0; --i)
    {
        while (k >= t && cross_product(ans[k - 2], ans[k - 1], A[i - 1]) <= 0)
            k--;
        ans[k++] = A[i - 1];
    }

    *hull_size = k - 1;
    return ans;
}

// Driver code
int main()
{
    struct Point points[] = {{0, 3}, {2, 2}, {1, 1}, {2, 1}, {3, 0}, {0, 0}, {3, 3}};
    int n = sizeof(points) / sizeof(points[0]);

    int hull_size;
    struct Point *ans = convex_hull(points, n, &hull_size);

    // Print the convex hull
    for (int i = 0; i < hull_size; i++)
        printf("(%lld, %lld)\n", ans[i].x, ans[i].y);

    // Free allocated memory
    free(ans);

    return 0;
}

Output
(0, 0)
(3, 0)
(3, 3)
(0, 3)

Time Complexity: O(n*log(n)) 
Auxiliary Space: O(n)

Convex Hull using QuickHull Algorithm in C

QuickHull is a divide-and-conquer algorithm that is similar to the QuickSort algorithm. It works by finding the convex hull points recursively by dividing the problem into smaller subproblems.

Approach:

  • Start finding the points with the minimum and maximum x-coordinates. These two points will always be part of the convex hull.
  • Draw a line connecting the minimum and maximum x-coordinate points. This line divides the set of points into two subsets. Each subset will be processed separately to find the points that form the convex hull.
  • For each subset, find the point that is farthest from the line connecting the two extreme points. This point, together with the two extreme points, forms a triangle.
  • Any points that lie inside this triangle cannot be part of the convex hull, so they can be eliminated.
  • Recursively apply the QuickHull algorithm to the remaining points outside the triangle, updating the convex hull as you go.
  • Combine the results from the recursive steps to form the final convex hull.

Below is the implementation of above approach:

C
// C program to implement Convex Hull using QuickHull Algorithm
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define iPair struct Pair

struct Pair
{
    int first;
    int second;
};

// Define a simple dynamic array structure for hull points
struct Hull
{
    iPair *points;
    int size;
    int capacity;
};

// Initialize the hull
void initHull(struct Hull *hull)
{
    hull->capacity = 10;
    hull->size = 0;
    hull->points = (iPair *)malloc(hull->capacity * sizeof(iPair));
}

// Add a point to the hull
void addPoint(struct Hull *hull, iPair p)
{
    if (hull->size == hull->capacity)
    {
        hull->capacity *= 2;
        hull->points = (iPair *)realloc(hull->points, hull->capacity * sizeof(iPair));
    }
    hull->points[hull->size++] = p;
}

// Check if a point is already in the hull
int isPointInHull(struct Hull *hull, iPair p)
{
    for (int i = 0; i < hull->size; i++)
    {
        if (hull->points[i].first == p.first && hull->points[i].second == p.second)
        {
            return 1;
        }
    }
    return 0;
}

// Free the memory used by the hull
void freeHull(struct Hull *hull)
{
    free(hull->points);
}

// Returns the side of point p with respect to the line joining points p1 and p2.
int findSide(iPair p1, iPair p2, iPair p)
{
    int val = (p.second - p1.second) * (p2.first - p1.first) - (p2.second - p1.second) * (p.first - p1.first);

    if (val > 0)
        return 1;
    if (val < 0)
        return -1;
    return 0;
}

// Returns a value proportional to the distance between the point p and the line joining the points p1 and p2.
int lineDist(iPair p1, iPair p2, iPair p)
{
    return abs((p.second - p1.second) * (p2.first - p1.first) -
               (p2.second - p1.second) * (p.first - p1.first));
}

// Recursively find the convex hull points
void quickHull(iPair a[], int n, iPair p1, iPair p2, int side, struct Hull *hull)
{
    int ind = -1;
    int max_dist = 0;

    for (int i = 0; i < n; i++)
    {
        int temp = lineDist(p1, p2, a[i]);
        if (findSide(p1, p2, a[i]) == side && temp > max_dist)
        {
            ind = i;
            max_dist = temp;
        }
    }

    if (ind == -1)
    {
        if (!isPointInHull(hull, p1))
        {
            addPoint(hull, p1);
        }
        if (!isPointInHull(hull, p2))
        {
            addPoint(hull, p2);
        }
        return;
    }

    quickHull(a, n, a[ind], p1, -findSide(a[ind], p1, p2), hull);
    quickHull(a, n, a[ind], p2, -findSide(a[ind], p2, p1), hull);
}

void printHull(iPair a[], int n)
{
    if (n < 3)
    {
        printf("Convex hull not possible\n");
        return;
    }

    int min_x = 0, max_x = 0;
    for (int i = 1; i < n; i++)
    {
        if (a[i].first < a[min_x].first)
            min_x = i;
        if (a[i].first > a[max_x].first)
            max_x = i;
    }

    struct Hull hull;
    initHull(&hull);

    quickHull(a, n, a[min_x], a[max_x], 1, &hull);
    quickHull(a, n, a[min_x], a[max_x], -1, &hull);

    printf("The points in Convex Hull are:\n");
    for (int i = 0; i < hull.size; i++)
    {
        printf("(%d, %d) ", hull.points[i].first, hull.points[i].second);
    }
    printf("\n");

    freeHull(&hull);
}

int main()
{
    iPair a[] = {{0, 3}, {1, 1}, {2, 2}, {4, 4}, {0, 0}, {1, 2}, {3, 1}, {3, 3}};
    int n = sizeof(a) / sizeof(a[0]);

    printHull(a, n);

    return 0;
}

Output
The points in Convex Hull are:
(0, 3) (4, 4) (0, 0) (3, 1) 

Time Complexity: The analysis is similar to Quick Sort. On average, we get time complexity as O(n Log n), but in worst case, it can become O(n2)
Auxilliary Space: O(n) 

Complexity Analysis

Convex Hull AlgorithmTime ComplexityDescription
Divide and Conquer AlgorithmO(N log N)Recursively divides the points and merges convex hulls.
Jarvis’ March (Wrapping)O(N^2)Simple but less efficient, wraps points in counterclockwise direction.
Graham ScanO(N log N)Sorts points and constructs the convex hull using stack.
Monotone Chain AlgorithmO(N log N)Sorts points and constructs upper and lower hulls separately.
QuickHull AlgorithmO(N log N)Similar to QuickSort, divides points using extreme points and recursively finds convex hulls.

Next Article
Article Tags :

Similar Reads