Kth Smallest Element in an Array
  • Twitter
  • Facebook
  • Snapchat
  • Instagram

36. Kth Smallest Element in an Array in C

šŸ“‘ On this page:
  • Introduction
  • C Program to Find Kth Smallest Element
  • Sample Output
  • Program Explanation
  • Step-by-Step Approach
  • Time & Space Complexity
  • Practice Exercise
  • Frequently Asked Questions
šŸ“š In this tutorial, you will learn:
  • What is the kth smallest element problem
  • Different approaches to find kth smallest element
  • Using sorting, selection, and heap-based approaches
  • Quick Select algorithm implementation
  • Time and space complexity analysis

Introduction to Kth Smallest Element

The kth smallest element problem asks us to find the element at position k when the array is sorted in ascending order. For example, in the array [7, 10, 4, 3, 20, 15], the 3rd smallest element is 7.

Key characteristics of this problem:

  • 1-indexed: k = 1 means the smallest element, k = n means the largest element
  • Multiple approaches: Can be solved using sorting, heap, or Quick Select
  • Common interview question: Tests understanding of sorting and selection algorithms
  • Applications: Used in statistics, order statistics, and data analysis

šŸ’” Example: For array [7, 10, 4, 3, 20, 15]:
1st smallest = 3, 2nd smallest = 4, 3rd smallest = 7, 4th smallest = 10, 5th smallest = 15, 6th smallest = 20

C Program to Find Kth Smallest Element

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

// Function to swap two elements
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// Partition function for Quick Select
int partition(int arr[], int low, int high) {
    int pivot = arr[high]; // Choose last element as pivot
    int i = low - 1; // Index of smaller element
    
    for (int j = low; j < high; j++) {
        if (arr[j] <= pivot) {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

// Quick Select function to find kth smallest element
// Note: k is 0-indexed (0 = smallest, n-1 = largest)
int quickSelect(int arr[], int low, int high, int k) {
    if (low == high) {
        return arr[low];
    }
    
    // Partition the array
    int pivotIndex = partition(arr, low, high);
    
    // If pivot is at k position, we found our element
    if (pivotIndex == k) {
        return arr[pivotIndex];
    }
    // If pivot is greater than k, search left side
    else if (pivotIndex > k) {
        return quickSelect(arr, low, pivotIndex - 1, k);
    }
    // If pivot is less than k, search right side
    else {
        return quickSelect(arr, pivotIndex + 1, high, k);
    }
}

// Approach 1: Using Sorting (Simple but O(n log n))
int kthSmallestBySorting(int arr[], int n, int k) {
    // Copy array to avoid modifying original
    int *temp = (int *)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        temp[i] = arr[i];
    }
    
    // Sort the array using bubble sort (for simplicity)
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (temp[j] > temp[j + 1]) {
                swap(&temp[j], &temp[j + 1]);
            }
        }
    }
    
    int result = temp[k - 1]; // k is 1-indexed
    free(temp);
    return result;
}

// Approach 2: Using Max Heap (O(n log k))
// Implementation using a simple max heap array
void maxHeapify(int heap[], int size, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    
    if (left < size && heap[left] > heap[largest]) {
        largest = left;
    }
    if (right < size && heap[right] > heap[largest]) {
        largest = right;
    }
    if (largest != i) {
        swap(&heap[i], &heap[largest]);
        maxHeapify(heap, size, largest);
    }
}

int kthSmallestUsingHeap(int arr[], int n, int k) {
    // Build max heap of first k elements
    int *heap = (int *)malloc(k * sizeof(int));
    for (int i = 0; i < k; i++) {
        heap[i] = arr[i];
    }
    for (int i = k / 2 - 1; i >= 0; i--) {
        maxHeapify(heap, k, i);
    }
    
    // For remaining elements, if smaller than heap root, replace
    for (int i = k; i < n; i++) {
        if (arr[i] < heap[0]) {
            heap[0] = arr[i];
            maxHeapify(heap, k, 0);
        }
    }
    
    int result = heap[0];
    free(heap);
    return result;
}

// Function to print the array
void printArray(int arr[], int n) {
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

// Driver program to test the kth smallest element
int main() {
    int arr[] = {7, 10, 4, 3, 20, 15, 8, 1, 6, 12};
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3; // Find 3rd smallest element
    
    printf("Array: ");
    printArray(arr, n);
    printf("k = %d\n\n", k);
    
    // Approach 1: Using Sorting
    int result1 = kthSmallestBySorting(arr, n, k);
    printf("Using Sorting: %dth smallest element = %d\n", k, result1);
    
    // Approach 2: Using Max Heap
    int result2 = kthSmallestUsingHeap(arr, n, k);
    printf("Using Max Heap: %dth smallest element = %d\n", k, result2);
    
    // Approach 3: Using Quick Select
    // Create a copy for Quick Select (it modifies the array)
    int *arrCopy = (int *)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        arrCopy[i] = arr[i];
    }
    int result3 = quickSelect(arrCopy, 0, n - 1, k - 1);
    printf("Using Quick Select: %dth smallest element = %d\n", k, result3);
    free(arrCopy);
    
    // Test with different k values
    printf("\nAll kth smallest elements:\n");
    for (int i = 1; i <= n; i++) {
        int *copy = (int *)malloc(n * sizeof(int));
        for (int j = 0; j < n; j++) {
            copy[j] = arr[j];
        }
        int result = quickSelect(copy, 0, n - 1, i - 1);
        printf("%dth smallest = %d\n", i, result);
        free(copy);
    }
    
    return 0;
}

Sample Output

Array: 7 10 4 3 20 15 8 1 6 12 
k = 3

Using Sorting: 3th smallest element = 6
Using Max Heap: 3th smallest element = 6
Using Quick Select: 3th smallest element = 6

All kth smallest elements:
1th smallest = 1
2th smallest = 3
3th smallest = 6
4th smallest = 7
5th smallest = 8
6th smallest = 10
7th smallest = 12
8th smallest = 15
9th smallest = 20
10th smallest = 7

Program Explanation

The program demonstrates three different approaches:

  1. Using Sorting (O(n log n)):
    • Sort the entire array using any sorting algorithm
    • Return the element at index k-1
    • Simple but not optimal for large arrays
  2. Using Max Heap (O(n log k)):
    • Build a max heap with first k elements
    • For each remaining element, if smaller than heap root, replace and heapify
    • At the end, the heap root contains the kth smallest element
    • More efficient for large n and small k
  3. Using Quick Select (O(n) average):
    • Based on Quick Sort's partitioning algorithm
    • Partition the array around a pivot
    • If pivot is at position k, we found our element
    • Otherwise, search the appropriate half
    • Average time complexity O(n)

Step-by-Step Approach for Quick Select

Step Action Explanation
1Choose PivotSelect the last element as pivot
2PartitionRearrange array so pivot is in its correct position
3Check PositionIf pivotIndex == k-1, we found the element
4Recurse LeftIf pivotIndex > k-1, search left half
5Recurse RightIf pivotIndex < k-1, search right half

Time & Space Complexity

Approach Time Complexity Space Complexity
Sorting O(n log n) O(n) - for copying
Max Heap O(n log k) O(k) - for heap
Quick Select O(n) average, O(n²) worst O(1) - in-place

šŸ“Š Recommendation:

  • For small arrays: Sorting is simplest and sufficient
  • For large n and small k: Max Heap approach is efficient
  • For general use: Quick Select is the best choice

šŸ’» Practice Exercise

Challenge 1: Modify the program to find the kth largest element instead of kth smallest.

Challenge 2: Implement kth smallest using a Min Heap and compare with Max Heap approach.

Challenge 3: Find the median of an array using Quick Select (median is the n/2-th smallest element).

šŸ” Click to Show Solution for Challenge 1
// To find kth largest, find (n-k+1)th smallest
int kthLargest(int arr[], int n, int k) {
    // Create copy for Quick Select
    int *copy = (int *)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        copy[i] = arr[i];
    }
    // kth largest = (n-k+1)th smallest
    int result = quickSelect(copy, 0, n - 1, n - k);
    free(copy);
    return result;
}

Frequently Asked Questions

1. What is the difference between kth smallest and kth largest?

Kth smallest is the element at position k when sorted ascending. Kth largest is the element at position k when sorted descending, or equivalently, the (n-k+1)th smallest element.

2. Why is Quick Select faster than sorting?

Quick Select only processes one half of the array at each step, resulting in O(n) average time, while sorting requires O(n log n) time to process the entire array.

3. When does Quick Select have O(n²) worst case?

Quick Select has worst-case O(n²) when the pivot always picks the smallest or largest element. This can be avoided by using random pivot selection or the median-of-medians algorithm.

4. Can I use this for arrays with duplicate elements?

Yes, the algorithm works with duplicates. The partition function uses <= comparison, so duplicates are handled correctly.

5. Which approach is best for finding the median?

Quick Select is excellent for finding the median (k = n/2) because it runs in O(n) average time, faster than sorting the entire array.

šŸ’” Pro Tip: In coding interviews, Quick Select is the preferred approach for order statistics problems. Always mention that it has O(n) average time complexity!

šŸ“– Related Tutorials

  • Quick Sort in C
  • Heap Sort in C
  • Selection Sort in C

Previous Topic: -->> Equilibrium Index in C   ||   Next topic: -->> Delete Duplicate Elements in C


C Language

  • Home
  • Why C Language
  • History of C Language
  • Applications of C Language
  • Introduction To C
    • What is Program?
    • Structure of C Program
    • Working Of C Program
    • CHARACTER SET
    • VARIABLES AND IDENTIFIERS
    • BUILT-IN DATA TYPES
    • OPERATORS AND EXPRESSIONS
    • CONSTANTS AND LITERALS
    • SIMPLE ASSIGNMENT STATEMENT
    • BASIC INPUT/OUTPUT STATEMENT
    • SIMPLE 'C' PROGRAMS
    • Assignments
  • Operators in C Programming
    • Arithmetic Operators
    • Assignment Operators
    • Increment and Decrement Operators
    • Relational Operators
    • Logical Operators
    • Bitwise Operators
    • Other Operators
    • Assignments
  • Conditional Statements
    • DECISION MAKING WITHIN A PROGRAM
    • CONDITIONS
    • IF STATEMENT
    • IF-ELSE STATEMENT
    • IF-ELSE LADDER
    • NESTED IF-ELSE
    • SWITCH CASE
    • Assignments
  • Loops Statements
    • Introduction to Loops
    • GO TO Statement
    • Do while Loop
    • While Loop
    • Nested While Loop
    • Difference Between While and Do while
    • Difference Between Goto and loop
    • while loop assignments
    • C FOR Loop
    • C For loop examples
    • Nested for loop
    • Nested for loop examples
    • Infinite while Loops
    • Infinite for Loops
    • Continue in Loops
    • break in Loops
    • difference while do..while & for
    • Assignments
  • Arrays
    • One Dimensional Array
    • Declaring 1D Arrays
    • Initilization of 1D arrays
    • Accessing element of one 1D Array
    • Read and Display 1D Arrays
    • Two Dimensional Arrays
    • Declare 2D Arrays
    • Read and Display 2D Arrays
    • Assignments/Examples
  • Functions
    • Introduction
    • Need For User-Defined Function
    • Multiple Function Program
    • Modular Programming
    • Elements Of User Defined Function
    • Function Definition
    • Function Declaration
    • Types of functions
    • Nesting of Function
    • Recursion
    • Passing Array To Functions
    • Scope,Visibility and Lifetime of Variables
    • Assignments
  • Structure
    • Introduction
    • Array vs Structure
    • Defining Structure
    • Declaring Structure Variables
    • Type Defined Structure
    • Accessing Structure Members
    • Structure Initilization
    • Copying & Comparing Structure Variables
    • Array of Structure
    • Arrays Within Structure
    • Structures Within Structures
    • Structures and Functions
    • Structure Examples/Assignments
  • Union
    • Define Union
    • Create and use Union
    • Difference Between Structure and Union
    • Union Examples
    • Union FAQ
  • Pointers
    • What Are Pointers In C?
    • How Do We Use Pointers In C?
    • Declaration Of A Pointer
    • The Initialization Of A Pointer
    • Syntax Of Pointer Initialization
    • Use Of Pointers In C
    • The Pointer To An Array
    • The Pointer To A Function
    • The Pointer To A Structure
    • Types Of Pointers
    • The Null Pointer
    • The Void Pointer
    • The Wild Pointer
    • The Near Pointer
    • The Huge Pointer
    • The far Pointer
    • dangling pointer
    • Accessing Pointers- Indirectly And Directly
    • Pros Of Using Pointers In C
    • Cons Of Pointers In C
    • Applications Of Pointers In C
    • The & Address Of Operator In C
    • How To Read The Complex Pointers In C?
    • Practice Problems On Pointers
  • File Processing
    • File Handling In C
    • Types Of Files In C
    • Operations Done In File Handling
    • File Examples
    • Binary Files
    • count words,lines in a file
    • Copy files
    • Update File
    • count vowels in a file
  • Preprocessor
    • Macro substitution division
    • File Inclusion
    • Conditional Compilation
    • Other directives
    • Examples
  • Dynamic Memory Allocation
    • malloc
    • calloc
    • free
    • realloc
    • Examples
  • Storage Classes
  • Graphics
  • Frequently Asked Interview Questions (FAQ)
    • Introduction To C FAQ
    • Operators FAQ
    • Conditional Statements FAQ
    • Loops FAQ
    • Arrays FAQ
    • Function FAQ
    • Structure FAQ
    • Pointers FAQ
    • Files FAQ
    • Storage classes FAQ
    • Dynamic Memory FAQ
  • Programs/Assignments
    • Introduction To C
    • Operators
    • Conditional Statements
    • Loops
    • Arrays
    • Function
    • Structure
    • Pointers
    • Files
    • Storage classes
    • Dynamic Memory
  • Case Studies
  • Multiple Choice Questions
    • Introduction To C MCQ
    • Operators MCQ
    • Conditional Statements MCQ
    • Loops MCQ
    • Arrays MCQ
    • Function MCQ
    • Structure MCQ
    • Pointers MCQ
    • Files MCQ
    • Storage classes MCQ
    • Dynamic Memory MCQ
    • More MCQ

Get in touch

  • tech2dsm@gmail.com

© Sankalan Data Tech. All rights reserved.