11.12 Insertion Sort

  • Another simple, but inefficient, sorting algorithm
  • First iteration takes the second element in the array and, if it’s less than the first element, swaps it with the first element
  • Second iteration looks at the third element and inserts it into the correct position with respect to the first two, so all three elements are in order
  • At the ith iteration of this algorithm, the first i elements in the original array will be sorted

11.12 Insertion Sort (cont.)

  • Consider the following array

    34 56 14 20 77 51 93 30 15 52

  • Insertion sort looks at the first two elements of the array, 34 and 56

    • Already in order, so the algorithm continues
    • If they were out of order, the algorithm would swap them
  • Next iteration looks at the third value, 14
    • Less than 56, so the program stores 14 in a temporary variable and moves 56 one element to the right
    • The algorithm then checks and determines that 14 is less than 34, so it moves 34 one element to the right
    • The algorithm has now reached the beginning of the array, so it places 14 in element 0
  • The array now is

    14 34 56 20 77 51 93 30 15 52

11.12 Insertion Sort (cont.)

  • Next iteration stores 20 in a temporary variable
    • Compares 20 to 56 and moves 56 one element to the right because it’s larger than 20
    • Next, compares 20 to 34, moving 34 right one element
    • When the algorithm compares 20 to 14, it observes that 20 is larger than 14 and places 20 in element 1
  • The array now is

    14 20 34 56 77 51 93 30 15 52

  • Using this algorithm, at the ith iteration, the first i elements of the original array are sorted, but may not be in their final locations
    • Smaller values may be located later in the array

11.12.1 Insertion Sort Implementation

Note: The last two lines of source code in this example have been modified from the print book so you can execute the example inside the notebook.

Function insertion_sort

  • In each iteration, variable insert holds the value of the element that will be inserted into the sorted portion of the array
  • Variable move_item keeps track of where to insert the element
  • The nested while loop locates the position where insert's value should be inserted
  • After the nested loop ends, the next statement inserts the element into place
In [1]:
# insertionsort.py
"""Sorting an array with insertion sort."""
import numpy as np
from ch11utilities import print_pass

def insertion_sort(data):
    """Sort an array using insertion sort."""
    # loop over len(data) - 1 elements      
    for next in range(1, len(data)):
        insert = data[next]  # value to insert 
        move_item = next  # location to place element

        # search for place to put current element         
        while move_item > 0 and data[move_item - 1] > insert:  
            # shift element right one slot
            data[move_item] = data[move_item - 1]         
            move_item -= 1                                      
                                              
        data[move_item] = insert  # place inserted element 
        print_pass(data, next, move_item)  # output pass of algorithm
In [2]:
def main(): 
    data = np.array([34, 56, 14, 20, 77, 51, 93, 30, 15, 52])
    print(f'Unsorted array: {data}\n')
    insertion_sort(data) 
    print(f'\nSorted array: {data}\n')
In [3]:
# call mainto execute the sort
main()
Unsorted array: [34 56 14 20 77 51 93 30 15 52]

after pass 1: 34  56* 14  20  77  51  93  30  15  52
              --  
after pass 2: 14* 34  56  20  77  51  93  30  15  52
              --  --  
after pass 3: 14  20* 34  56  77  51  93  30  15  52
              --  --  --  
after pass 4: 14  20  34  56  77* 51  93  30  15  52
              --  --  --  --  
after pass 5: 14  20  34  51* 56  77  93  30  15  52
              --  --  --  --  --  
after pass 6: 14  20  34  51  56  77  93* 30  15  52
              --  --  --  --  --  --  
after pass 7: 14  20  30* 34  51  56  77  93  15  52
              --  --  --  --  --  --  --  
after pass 8: 14  15* 20  30  34  51  56  77  93  52
              --  --  --  --  --  --  --  --  
after pass 9: 14  15  20  30  34  51  52* 56  77  93
              --  --  --  --  --  --  --  --  --  

Sorted array: [14 15 20 30 34 51 52 56 77 93]

11.12.2 Big O of the Insertion Sort

  • Insertion sort also runs in O(n2) time
  • Algorithm contains nested loops
  • The outer for loop iterates len(data) - 1 times, inserting an element into the appropriate position among the elements sorted so far
    • len(data) - 1 is equivalent to n – 1 (as len(data) is the size of the array)
  • The nested while loop iterates over the preceding elements in the array
    • Worst case, this loop requires n – 1 comparisons
    • Each iteration runs in O(n) time
  • In Big O notation, nested loops mean that you must multiply the number of comparisons
    • For each iteration of an outer loop, there will be a certain number of iterations of the inner loop
    • In this algorithm, for each O(n) iterations of the outer loop, there will be O(n) iterations of the inner loop
    • Multiplying these values results in O(n2)

©1992–2020 by Pearson Education, Inc. All Rights Reserved. This content is based on Chapter 5 of the book Intro to Python for Computer Science and Data Science: Learning to Program with AI, Big Data and the Cloud.

DISCLAIMER: The authors and publisher of this book have used their best efforts in preparing the book. These efforts include the development, research, and testing of the theories and programs to determine their effectiveness. The authors and publisher make no warranty of any kind, expressed or implied, with regard to these programs or to the documentation contained in these books. The authors and publisher shall not be liable in any event for incidental or consequential damages in connection with, or arising out of, the furnishing, performance, or use of these programs.