CS1033 L10 Search Sort
CS1033 L10 Search Sort
1 / 46
Acknowledgment
2 / 46
Contents
◮ Introduction
3 / 46
Contents
◮ Introduction
◮ Searching algorithms
◮ Sequential search
◮ Binary search
3 / 46
Contents
◮ Introduction
◮ Searching algorithms
◮ Sequential search
◮ Binary search
◮ Sorting algorithms
◮ Bubble sort
◮ Selection sort
◮ Insertion sort
◮ Shell sort
◮ Merge sort
◮ Quick sort
◮ Heap sort
3 / 46
Introduction
4 / 46
Introduction
4 / 46
Sequential Search
5 / 46
Sequential Search
5 / 46
Iterative Sequential Search
1 def sequential_search(a_list, item):
2 pos = 0
3 found = False
4
5 while pos < len(a_list) and not found:
6 if a_list[pos] == item:
7 found = True
8 else:
9 pos = pos+1
10
11 if found:
12 return pos
13 else:
14 return -1
15
16 test_list = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
17 print(sequential_search(test_list, 3))
6 / 46
Recursive Sequential Search
7 / 46
Binary Search
The binary search algorithm can be used to search for an item in
any ordered collection such as a list.
8 / 46
Binary Search
The binary search algorithm can be used to search for an item in
any ordered collection such as a list.
10 / 46
Recursive binary search examples
11 / 46
Time Complexities of Search Algorithms
12 / 46
Sorting
13 / 46
Sorting
13 / 46
Bubble Sort 1/2
The bubble sort algorithm makes multiple passes through a
collection and compare adjacent items to reorder those that are
out of order.
14 / 46
Bubble Sort 1/2
The bubble sort algorithm makes multiple passes through a
collection and compare adjacent items to reorder those that are
out of order.
◮ Each pass through the list would place the next largest item
at its correct position while reducing the size of the remaining
collection to be sorted by one.
◮ Bubble sort will make n − 1 passes to sort a list of n items
and the total
Pn−1number of comparisons is the sum of first n − 1
integers ( i=1 i = n(n−1)
2 = 12 n2 − 21 n).
◮ Bubble sort will make no swaps in the best case (for an
already ordered list) and a swap for every comparison in the
worst case (for a collection sorted in the reverse order).
◮ An improvement of this algorithm is to terminate it early if
there were no swaps performed during a pass through the list,
which indicate that the list is sorted in order at that point.
14 / 46
Bubble Sort (iterative) 2/2
1 def bubble_sort(a_list):
2 # outer loop
3 for j in range(len(a_list) - 1, 0, -1):
4 # inner loop
5 for i in range(j):
6 if a_list[i] > a_list[i + 1]:
7 # do a swap
8 temp = a_list[i]
9 a_list[i] = a_list[i + 1]
10 a_list[i + 1] = temp
11
12 a_list = [54, 26, 93, 17, 77, 31, 44, 55, 20]
13 bubble_sort(a_list)
14 print(a_list)
15 / 46
Selection Sort 1/2
16 / 46
Selection Sort 1/2
16 / 46
Selection Sort (iterative) 2/2
1 def selection_sort(a_list):
2 # outer loop
3 for j in range(len(a_list) - 1, 0, -1):
4 pos_of_max = 0
5 # inner loop
6 for i in range(1, j + 1):
7 if a_list[i] > a_list[pos_of_max]:
8 pos_of_max = i
9 # do a swap
10 temp = a_list[j]
11 a_list[j] = a_list[pos_of_max]
12 a_list[pos_of_max] = temp
13
14 a_list = [54, 26, 93, 17, 77, 31, 44, 55, 20]
15 selection_sort(a_list)
16 print(a_list)
17 / 46
Selection sort example
start [54, 26, 93, 17, 77, 31, 44, 55, 20]
pass 8 [54, 26, 20, 17, 77, 31, 44, 55, 93]
pass 7 [54, 26, 20, 17, 55, 31, 44, 77, 93]
pass 6 [54, 26, 20, 17, 44, 31, 55, 77, 93]
pass 5 [31, 26, 20, 17, 44, 54, 55, 77, 93]
pass 4 [31, 26, 20, 17, 44, 54, 55, 77, 93]
pass 3 [17, 26, 20, 31, 44, 54, 55, 77, 93]
pass 2 [17, 20, 26, 31, 44, 54, 55, 77, 93]
pass 1 [17, 20, 26, 31, 44, 54, 55, 77, 93]
18 / 46
Selection sort example
19 / 46
Insertion Sort 1/2
20 / 46
Insertion Sort 1/2
20 / 46
Insertion Sort (iterative) 2/2
1 def insertion_sort(a_list):
2 for index in range(1, len(a_list)):
3 current_value = a_list[index]
4 pos = index
5
6 while pos > 0 and a_list[pos - 1] > current_value:
7 a_list[pos] = a_list[pos - 1]
8 pos = pos - 1
9
10 a_list[pos] = current_value
11
12 a_list = [54, 26, 93, 17, 77, 31, 44, 55, 20]
13 insertion_sort(a_list)
14 print(a_list)
start [54, 26, 93, 17, 77, 31, 44, 55, 20]
pass 1 [26, 54, 93, 17, 77, 31, 44, 55, 20]
pass 2 [26, 54, 93, 17, 77, 31, 44, 55, 20]
pass 3 [17, 26, 54, 93, 77, 31, 44, 55, 20]
pass 4 [17, 26, 54, 77, 93, 31, 44, 55, 20]
pass 5 [17, 26, 31, 54, 77, 93, 44, 55, 20]
pass 6 [17, 26, 31, 44, 54, 77, 93, 55, 20]
pass 7 [17, 26, 31, 44, 54, 55, 77, 93, 20]
pass 8 [17, 20, 26, 31, 44, 54, 55, 77, 93]
22 / 46
Insertion sort example
23 / 46
Shell Sort 1/3
24 / 46
Shell Sort 1/3
24 / 46
Shell Sort (iterative) 2/3
1 def shell_sort(a_list):
2 sublist_count = len(a_list) // 2
3
4 while sublist_count > 0:
5 for start_pos in range(sublist_count):
6 gap_insertion_sort(a_list,start_pos,sublist_count)
7
8 print("After increments of size", sublist_count,
"The list is",a_list)
9
10 sublist_count = sublist_count // 2
11
25 / 46
Shell Sort (iterative) 3/3
26 / 46
Shell sort example
sort [54, 26, 93, 17, 77, 31, 44, 55, 20] with sublist size 4
4 [54, 26, 93, 17, 77, 31, 44, 55, 20]
8 [20, 26, 93, 17, 54, 31, 44, 55, 77]
5 [20, 26, 93, 17, 54, 31, 44, 55, 77]
6 [20, 26, 44, 17, 54, 31, 93, 55, 77]
7 [20, 26, 44, 17, 54, 31, 93, 55, 77]
sort [20, 26, 44, 17, 54, 31, 93, 55, 77] with sublist size 2
2 [20, 26, 44, 17, 54, 31, 93, 55, 77]
4 [20, 26, 44, 17, 54, 31, 93, 55, 77]
6 [20, 26, 44, 17, 54, 31, 93, 55, 77]
8 [20, 26, 44, 17, 54, 31, 77, 55, 93]
3 [20, 17, 44, 26, 54, 31, 77, 55, 93]
5 [20, 17, 44, 26, 54, 31, 77, 55, 93]
7 [20, 17, 44, 26, 54, 31, 77, 55, 93]
sort [20, 17, 44, 26, 54, 31, 77, 55, 93] with sublist size 1
1 [17, 20, 44, 26, 54, 31, 77, 55, 93]
2 [17, 20, 44, 26, 54, 31, 77, 55, 93]
3 [17, 20, 26, 44, 54, 31, 77, 55, 93]
4 [17, 20, 26, 44, 54, 31, 77, 55, 93]
5 [17, 20, 26, 31, 44, 54, 77, 55, 93]
6 [17, 20, 26, 31, 44, 54, 77, 55, 93]
7 [17, 20, 26, 31, 44, 54, 55, 77, 93]
8 [17, 20, 26, 31, 44, 54, 55, 77, 93]
27 / 46
Shell sort example
28 / 46
Merge Sort 1/3
Merge sort is a recursive algorithm that continually splits a list in
half.
29 / 46
Merge Sort 1/3
Merge sort is a recursive algorithm that continually splits a list in
half.
32 / 46
Merge sort - splitting example
33 / 46
Merge sort - merging example
34 / 46
Quick Sort 1/3
Quick sort is a recursive algorithm that use the divide and conquer
strategy to continually split a list around a selected value called the
split point.
35 / 46
Quick Sort 1/3
Quick sort is a recursive algorithm that use the divide and conquer
strategy to continually split a list around a selected value called the
split point.
39 / 46
Heap Sort 1/5
39 / 46
Heap Sort 2/5
40 / 46
Heap Sort 2/5
40 / 46
Heap Sort 3/5
41 / 46
Heap Sort 4/5
# To heapify subtree rooted at index i. Heap size is n.
def heapify(a_list, n, i):
largest = i # Initialize largest as root
l = 2 * i + 1 # left = 2*i + 1
r = 2 * i + 2 # right = 2*i + 2
def heap_sort(a_list):
n = len(a_list)
a_list = [54, 26, 93, 17, 77, 31, 44, 55, 20]
heap_sort(a_list)
print(a_list)
43 / 46
Heap sort example
input
[54, 26, 93, 17, 77, 31, 44, 55, 20]
build max heap
[54, 26, 93, 55, 77, 31, 44, 17, 20]
[54, 26, 93, 55, 77, 31, 44, 17, 20]
[54, 77, 93, 55, 26, 31, 44, 17, 20]
[93, 77, 54, 55, 26, 31, 44, 17, 20]
progressively sort
[77, 55, 54, 20, 26, 31, 44, 17, 93]
[55, 26, 54, 20, 17, 31, 44, 77, 93]
[54, 26, 44, 20, 17, 31, 55, 77, 93]
[44, 26, 31, 20, 17, 54, 55, 77, 93]
[31, 26, 17, 20, 44, 54, 55, 77, 93]
[26, 20, 17, 31, 44, 54, 55, 77, 93]
[20, 17, 26, 31, 44, 54, 55, 77, 93]
[17, 20, 26, 31, 44, 54, 55, 77, 93]
[17, 20, 26, 31, 44, 54, 55, 77, 93]
44 / 46
Time Complexities of Sorting Algorithms
45 / 46
Exercise
Implement the algorithms discussed in this lecture and test them
with following timing measurements code inserted.
1 import time
2
3 # the searching or sorting function
...
40 a_list = [54, 26, 93, 17, 77, 31, 44, 55, 20]
41 print(a_list)
42 start_time = time.time()
43 function_name(a_list)
44 end_time = time.time() - start_time
45 print(a_list)
46 print("execution time is %s seconds" % end_time)