Chapter 6 — Sorting, Searching, Sub-programs & Testing
Master algorithm design for the HKDSE ICT exam. Learn flowcharts, pseudocode, bubble sort, insertion sort, linear search, binary search, functions, procedures, and debugging techniques.
Algorithm representation, flowcharts, pseudocode, sorting & searching fundamentals
Bubble sort, insertion sort, linear search, binary search, sub-programs
Testing strategies, error types, debugging, trace tables
Test your understanding with 12 multiple-choice questions
20 interactive flashcards covering key terms and concepts
Practice with 6 past exam-style questions
An algorithm is a step-by-step set of instructions to solve a problem. Algorithms can be represented in three ways: flowcharts, pseudocode, and program code.
INPUT, OUTPUT
IF-THEN-ELSE-ENDIF
WHILE-ENDWHILE
FOR-NEXT
REPEAT-UNTIL
| Aspect | Flowchart | Pseudocode |
|---|---|---|
| Format | Visual diagram with symbols | Text-based structured English |
| Advantage | Easy to understand logic flow | Closer to actual code |
| Disadvantage | Complex for large programs | Less visual clarity |
Flowcharts and pseudocode are both tested in DSE Paper 2!
Sorting is the process of arranging data in a specific order (ascending or descending). It enables faster searching and better data organization.
Searching algorithms find specific data within a collection. The choice of algorithm depends on whether the data is sorted.
| Aspect | Linear Search | Binary Search |
|---|---|---|
| Method | Check one by one | Divide and conquer |
| Requirement | Works on any data | Requires sorted data |
| Time Complexity | O(n) | O(log n) |
| Example (1000 items) | Up to 1000 comparisons | At most 10 comparisons |
Sub-programs are reusable blocks of code that perform specific tasks. They improve code modularity and maintainability.
In Python, both functions and procedures use the def keyword.
Bubble sort repeatedly compares adjacent elements and swaps them if they are in the wrong order. The largest element "bubbles" to the end after each complete pass.
def bubble_sort(data):
n = len(data)
for i in range(n - 1):
swapped = False
for j in range(n - 1 - i):
if data[j] > data[j + 1]:
data[j], data[j + 1] = data[j + 1], data[j]
swapped = True
if not swapped:
break
| Pass | List State | Comparisons |
|---|---|---|
| Initial | [5, 3, 8, 1, 2] | - |
| Pass 1 | [3, 5, 1, 2, 8] | 4 |
| Pass 2 | [3, 1, 2, 5, 8] | 3 |
| Pass 3 | [1, 2, 3, 5, 8] | 2 |
| Pass 4 | [1, 2, 3, 5, 8] | No swaps - sorted! |
Insertion sort builds the sorted portion one element at a time by inserting each element into its correct position. It works like sorting playing cards in your hand.
def insertion_sort(data):
for i in range(1, len(data)):
key = data[i]
j = i - 1
while j >= 0 and data[j] > key:
data[j + 1] = data[j]
j -= 1
data[j + 1] = key
| Iteration | Key | List State |
|---|---|---|
| Initial | - | [5, 3, 8, 1, 2] |
| i=1 | 3 | [3, 5, 8, 1, 2] |
| i=2 | 8 | [3, 5, 8, 1, 2] |
| i=3 | 1 | [1, 3, 5, 8, 2] |
| i=4 | 2 | [1, 2, 3, 5, 8] |
Linear search checks each element one by one from start to end until the target is found or the end is reached.
def linear_search(data, target):
for i in range(len(data)):
if data[i] == target:
return i # Return index if found
return -1 # Return -1 if not found
Time Complexity: O(n) - worst case checks all elements
Binary search only works on sorted data. It repeatedly divides the search space in half, making it much faster than linear search.
def binary_search(data, target):
low = 0
high = len(data) - 1
while low <= high:
mid = (low + high) // 2
if data[mid] == target:
return mid
elif target < data[mid]:
high = mid - 1
else:
low = mid + 1
return -1
| Step | low | high | mid | data[mid] | Action |
|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 7 | Found! |
Time Complexity: O(log n) - much faster than linear search
def calculate_area(length, width):
return length * width
result = calculate_area(5, 3) # result = 15
def display_greeting(name):
print("Hello, " + name + "!")
display_greeting("Alice") # Prints: Hello, Alice!
Testing verifies that a program produces correct output for various inputs. Different types of test data are used to ensure comprehensive coverage.
| Test Case | Input | Expected Output | Actual Output | Pass/Fail |
|---|---|---|---|---|
| Normal | 5 | 120 | 120 | Pass |
| Boundary | 0 | 1 | 1 | Pass |
| Abnormal | -5 | Error message | Error message | Pass |
Violates language rules. Detected by the interpreter before/during execution.
# Example: Missing colon
if x > 5 # SyntaxError: invalid syntax
print("Greater")
Program crashes during execution due to invalid operations.
# Example: Division by zero
result = 10 / 0 # ZeroDivisionError
# Example: Index out of range
data = [1, 2, 3]
print(data[5]) # IndexError
Program runs but produces incorrect output. Hardest to find!
# Example: Wrong loop boundary
# Should print 1 to 10, but only prints 1 to 9
for i in range(1, 10): # Should be range(1, 11)
print(i)
Trace tables track variable values step by step during code execution. They are essential for understanding algorithm behavior and finding logic errors.
Trace tables are one of the most commonly tested skills in DSE Paper 2!
Complete trace of one pass of bubble sort on [5, 3, 8, 1]:
| Comparison | j | Compare | Swap? | List |
|---|---|---|---|---|
| Initial | - | - | - | [5, 3, 8, 1] |
| 1 | 0 | 5 vs 3 | Yes | [3, 5, 8, 1] |
| 2 | 1 | 5 vs 8 | No | [3, 5, 8, 1] |
| 3 | 2 | 8 vs 1 | Yes | [3, 5, 1, 8] |
def gcd(a, b):
while b != 0:
temp = b
b = a % b
a = temp
return a
result = gcd(48, 18) # result = 6
def is_palindrome(text):
text = text.lower().replace(" ", "")
return text == text[::-1]
print(is_palindrome("A man a plan a canal Panama")) # True
choice = 0
while choice != 4:
print("1. Enter data")
print("2. Sort data")
print("3. Search data")
print("4. Exit")
choice = int(input("Choice: "))
if choice == 1:
# Enter data code
pass
elif choice == 2:
# Sort data code
pass
elif choice == 3:
# Search data code
pass
Test your understanding with 12 multiple-choice questions
Click any card to flip and reveal the answer
Practice with exam-style questions