Chapter 2
Chapter 2
Binary search is performed from the middle of the array rather than the end. We keep track of
low and high, which delimit the portion of the array in which an item, if present, must reside.
Initially, the range is from 0 to N - 1. If low is larger than high, we know that the item is not
present, so we return NOT-FOUND. Otherwise, we let mid be the halfway point of the range
(rounding down if the range has an even number of elements) and compare the item we are
searching for with the item in position mid. If we find a match, we are done and can return. If the
item we are searching for is less than the item in position mid, then it must reside in the range
low to mid-1. If it is greater, then it must reside in the range mid+l to high.
Implementation example:
The insertion sort works just like its name suggests - it inserts each item into its proper place in
the final list. The simplest implementation of this requires two list structures - the source list and
the list into which sorted items are inserted. To save memory, most implementations use an in-
place sort that works by moving the current item past the already sorted items and repeatedly
swapping it with the preceding item until it is in place.
It's the most instinctive type of sorting algorithm. The approach is the same approach that you
use for sorting a set of cards in your hand. While playing cards, you pick up a card, start at the
beginning of your hand and find the place to insert the new card, insert it and move all the others
up one place.
Find the location for an element and move all others up, and insert the element.
The left most value can be said to be sorted relative to itself. Thus, we don’t need to do anything.
Check to see if the second value is smaller than the first one. If it is, swap these two values. The
first two values are now relatively sorted.
Next, we need to insert the third value in to the relatively sorted portion so that after insertion,
the portion will still be relatively sorted.
Remove the third value first. Slide the second value to make room for insertion. Insert the value
in the appropriate position.
Now the first three are relatively sorted.
Do the same for the remaining items in the list.
Implementation example:
The following figure shows how the array [5 2 3 8 1] is sorted by insertion sort.
To find the number of comparisons performed by insertion sort algorithm, observe first that the
outer for loop always performs n-1 iterations. The best case is when the data are already in order.
Only one comparison is made for each position i, so there are n - 1 comparisons, which is O(n), ,
and 2(n - 1) moves, all of them redundant.
The worst case is when the data are in reverse order. In this case, for each i, the item data[i] is
less than every item data[0], . . . , data[i-1], and each of them is moved by one position. For each
iteration i of the outer for loop, there are i comparisons, and the total number of comparisons for
all iterations of this loop is
𝒏(𝒏−𝟏)
∑𝒏−𝟏
𝒊=𝟏 (𝒊) = 1 + 2 + 3+ . . . + (n-1) = = O(n2)
𝟐
The number of times the assignment in the inner for loop is executed can be computed using the
same formula. The number of times temp is loaded and unloaded in the outer for loop is added to
that, resulting in the total number of moves
𝒏(𝒏−𝟏) 𝒏𝟐 +𝟑𝒏 − 𝟒
+ 2 (n - 1) = = O(n2)
𝟐 𝟐
Selection sort is an attempt to localize the exchanges of array elements by finding a misplaced
element first and putting it in its final place. The element with the lowest value is selected and
exchanged with the element in the first position. Then, the smallest value among the remaining
elements data[1], . . . , data[n-1] is found and put in the second position. This selection and
placement by finding, in each pass i, the lowest value among the elements data[i], . . . , data[n-1]
and swapping it with data[i] are continued until all elements are in their proper positions.
It is rather obvious that n-2 should be the last value for i, because if all elements but the last have
been already considered and placed in their proper positions, then the nth element (occupying
position n-1) has to be the largest.
Implementation example:
The following figure shows how the array [5 2 3 8 1] is sorted by selection sort.
Note: least in the implementation and figure above is not the smallest element but its position.
The analysis of the performance of the function Selection_Sort ( ) is simplified by the presence
of two for loops with lower and upper bounds. The outer loop executes n - 1 times, and for each i
between 0 and n - 2, the inner loop iterates j = (n -1) - i times. Because comparisons of keys are
done in the inner loop, there are
𝒏(𝒏−𝟏)
∑𝒏−𝟐
𝒊=𝟎 (𝒏 − 𝟏 − 𝒊) = (n-1) + (n-2) + (n-3) + . . . + 3 + 2 + 1 = = O(n2)
𝟐
bubblesort(data[ ] , n)
for i = 0 to n - 2
for j = n-1down to i+1
swap elements in positions j and j-1 if they are out of order;
Bubble sort is the simplest algorithm to implement and the slowest algorithm on very large
inputs.
Loop through array from i=0 to n and swap adjacent elements if they are out of order.
The following figure shows how the array [5 2 3 8 1] is sorted by bubble sort.
The number of comparisons is the same in each case (best, average, and worst) and equals the
total number of iterations of the inner for loop
𝒏(𝒏−𝟏)
∑𝒏−𝟐
𝒊=𝟐 (𝒏 − 𝟏 − 𝒊) = = O(n2)
𝟐
comparisons. This formula also computes the number of swaps in the worst case when the array
𝒏(𝒏−𝟏)
is in reverse order. In this case, 3 = O(n2) moves have to be made. The best case, when
𝟐
all elements are already ordered, requires no swaps.