Sorting is one of the most important concepts in programming. It helps us organize data so that we can search, access, and manage it more efficiently. Among the many sorting algorithms available, Insertion Sort stands out as one of the easiest for beginners to understand. It works the same way we sort playing cards in our hands — we pick up one card at a time and insert it in the correct position relative to the cards we’ve already sorted.
with hands-on learning.
get the skills and confidence to land your next move.
Insertion Sort is not the fastest algorithm, especially when dealing with large datasets, but it shines in its simplicity. It’s a great starting point for anyone learning how sorting algorithms work. This method is most effective for small lists or nearly sorted data. In programming education, Insertion Sort is often used to teach ideas such as nested loops, shifting elements, and comparison logic. In this article, we’ll explore different ways to implement Insertion Sort in Kotlin using loops, recursion, and a few creative variations to help you understand it from all angles.
Program 1: Basic Insertion Sort using Loops
This is the most common way to write an Insertion Sort program. It uses loops to compare and shift elements until every element is in the correct place.
fun main() {
val numbers = intArrayOf(9, 5, 1, 4, 3)
println("Original Array: ${numbers.joinToString()}")
for (i in 1 until numbers.size) {
val key = numbers[i]
var j = i - 1
while (j >= 0 && numbers[j] > key) {
numbers[j + 1] = numbers[j]
j--
}
numbers[j + 1] = key
}
println("Sorted Array: ${numbers.joinToString()}")
}In this program, the algorithm starts from the second element and compares it with the ones before it. If the current element is smaller than its predecessor, it keeps moving the larger elements one position ahead to make space for the smaller one. This continues until all elements are sorted. Beginners often find this version easy to understand because it closely resembles the way humans naturally sort things in real life.
Program 2: Optimized Insertion Sort with Early Exit
This version of the algorithm includes a small optimization to check whether the array is already sorted, helping it finish faster when no shifting is needed.
fun main() {
val numbers = intArrayOf(2, 4, 6, 8, 10)
println("Original Array: ${numbers.joinToString()}")
var isSorted = true
for (i in 1 until numbers.size) {
val key = numbers[i]
var j = i - 1
while (j >= 0 && numbers[j] > key) {
numbers[j + 1] = numbers[j]
j--
isSorted = false
}
numbers[j + 1] = key
if (isSorted) break
}
println("Sorted Array: ${numbers.joinToString()}")
}In this version, a flag named isSorted is introduced to check if any shifting occurs during the process. If no elements are moved, it means the array is already sorted, and the loop breaks early. This is a simple improvement but a useful one for small, nearly sorted datasets. It also teaches beginners the value of adding checks to make algorithms more efficient without complicating the logic.
Program 3: Recursive Insertion Sort
Here we use recursion to implement Insertion Sort. Instead of using loops, the function calls itself to handle smaller portions of the array.
fun insertionSortRecursive(arr: IntArray, n: Int) {
if (n <= 1) return
insertionSortRecursive(arr, n - 1)
val last = arr[n - 1]
var j = n - 2
while (j >= 0 && arr[j] > last) {
arr[j + 1] = arr[j]
j--
}
arr[j + 1] = last
}
fun main() {
val numbers = intArrayOf(12, 11, 13, 5, 6)
println("Original Array: ${numbers.joinToString()}")
insertionSortRecursive(numbers, numbers.size)
println("Sorted Array: ${numbers.joinToString()}")
}In this recursive approach, the function first sorts the smaller part of the array and then places the last element in its correct position. Recursion may seem tricky at first, but once you understand the flow, it becomes clear how it reduces the problem step by step. This version is a great way for learners to connect the concepts of recursion with sorting, strengthening both topics in one go.
Program 4: Insertion Sort in Descending Order
Sometimes, we need to sort numbers from largest to smallest. This version modifies the comparison logic to sort in descending order.
fun main() {
val numbers = intArrayOf(3, 1, 9, 7, 5)
println("Original Array: ${numbers.joinToString()}")
for (i in 1 until numbers.size) {
val key = numbers[i]
var j = i - 1
while (j >= 0 && numbers[j] < key) {
numbers[j + 1] = numbers[j]
j--
}
numbers[j + 1] = key
}
println("Sorted in Descending Order: ${numbers.joinToString()}")
}The logic here is almost identical to the ascending version, except that the comparison numbers[j] < key is used instead of numbers[j] > key. This change flips the sorting direction, arranging elements from largest to smallest. It’s a simple modification that shows how flexible Insertion Sort can be. By experimenting with conditions like this, beginners learn how to adjust algorithms for different types of sorting needs.
Program 5: Insertion Sort Using Kotlin Functions
This version wraps the sorting logic in a reusable Kotlin function. It keeps the code clean and modular, which is a good practice for larger projects.
fun insertionSort(arr: IntArray): IntArray {
for (i in 1 until arr.size) {
val key = arr[i]
var j = i - 1
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j]
j--
}
arr[j + 1] = key
}
return arr
}
fun main() {
val numbers = intArrayOf(10, 3, 15, 7, 8, 23, 98, 29)
println("Original Array: ${numbers.joinToString()}")
val sortedArray = insertionSort(numbers)
println("Sorted Array: ${sortedArray.joinToString()}")
}Here, the sorting logic is placed inside a function named insertionSort. It can be called anytime with any integer array, making it reusable and easier to test. This version also introduces beginners to the idea of organizing code into functions, an important step in writing clean, maintainable Kotlin programs.
Frequently Asked Questions (FAQ)
This section answers some common questions that new learners often have about Insertion Sort in Kotlin.
Q1: What is Insertion Sort in Kotlin?
Insertion Sort is a simple sorting algorithm that works by picking elements one by one and inserting them in their correct position within the sorted portion of the array.
Q2: Is Insertion Sort efficient for large arrays?
No, Insertion Sort has a time complexity of O(n²), which makes it slow for large datasets. However, it performs well for small or nearly sorted arrays.
Q3: Can Insertion Sort be used for strings in Kotlin?
Yes, it can. You just need to adjust the comparison logic to work with strings instead of integers.
Q4: What is the main difference between Bubble Sort and Insertion Sort?
Bubble Sort compares adjacent elements and repeatedly swaps them, while Insertion Sort builds the sorted portion step by step by inserting each element in the right spot.
Q5: Does Insertion Sort maintain the order of equal elements?
Yes, Insertion Sort is a stable sorting algorithm, which means that equal elements retain their relative order.
Conclusion
Insertion Sort might be simple, but it’s a wonderful starting point for anyone learning about sorting algorithms in Kotlin. It demonstrates how comparison and shifting work together to organize data efficiently. Though it’s not ideal for large datasets, it’s perfect for understanding the mechanics of sorting and algorithm design.
By trying different versions — from basic loops to recursion and descending order — you’ll develop a deeper understanding of how sorting works under the hood. As you practice, you’ll begin to see patterns that connect many algorithms, helping you grow as a programmer. So, open your Kotlin editor, play around with these examples, and enjoy the process of watching your data fall into perfect order — one insertion at a time.




