Sort Visualiser
Enter a comma-separated list of numbers, pick bubble sort or selection sort, and step through each comparison. Amber bars are being compared; red means a swap just happened; violet means an element has settled into its final sorted position.
Step Through a Sort
● liveBubble Sort
Bubble sort arranges a list of elements in ascending or descending order. The algorithm moves through the list and compares each pair of adjacent elements — if they are in the wrong order, they are swapped. Bubble sort gets its name because the larger element "bubbles" towards the end of the list.
To sort a list containing N elements, bubble sort requires (N − 1) passes. During each pass, the number of elements to be compared reduces by one, since the largest remaining element always moves to its correct position at the end.
Algorithm for Bubble Sort (ascending order)
- Step 1: Start.
- Step 2: Accept a value in N as the number of elements of the list.
- Step 3: Accept N elements into the list named LIST.
- Step 4: Repeat Steps 5 to 7, (N − 1) times.
- Step 5: Repeat Step 6 until the second last element of the current list.
- Step 6: Starting from the first position, compare two adjacent elements in the list. If they are not in the proper order, swap the elements.
- Step 7: Revise the list by excluding the last element in the current list.
- Step 8: Print the sorted list, LIST.
- Step 9: Stop.
To improve clarity and maintainability, Python encourages dividing large code blocks into smaller, well-defined functions. Following this approach, the bubble sort steps (5 to 7) are separated into a dedicated bubble_sort() function.
# Traverse through all elements in the list def bubble_sort(LIST, n): for i in range(n - 1): # Last i elements are already in place for j in range(0, n - i - 1): # Swap if element found is greater than next element if LIST[j] > LIST[j + 1]: LIST[j], LIST[j + 1] = LIST[j + 1], LIST[j] return LIST # Accept number of elements count = int(input("Enter how many numbers: ")) # Create an empty list ITEMS = [] # Accept n numbers from the user for i in range(count): num = int(input(f"Enter number {i+1}: ")) ITEMS.append(num) # Display the list print("Original list:", ITEMS) # Display the sorted list print("Sorted list:", bubble_sort(ITEMS, count))
Enter how many numbers: 5 Enter number 1: 56 Enter number 2: 34 Enter number 3: 98 Enter number 4: 12 Enter number 5: 39 Original list: [56, 34, 98, 12, 39] Sorted list: [12, 34, 39, 56, 98]
Selection Sort
To sort a list in ascending order, selection sort starts by finding the smallest value in the list and placing it in the first position — the element originally at the first position is shifted to where the smallest element was. This is repeated to find the second smallest, and so on, until the entire list is sorted.
A pass is completed once the smallest element in the unsorted section is located and exchanged with the element at the current position. For N elements there will be N − 1 passes. Though each pass is intended for an exchange, no exchange is made if the smallest value is already in the correct location — as seen in Pass 3 above.
Algorithm for Selection Sort
- Step 1: Start.
- Step 2: Accept a value in N as the number of elements of the list.
- Step 3: Accept N elements into the list named LIST.
- Step 4: Repeat Steps 5 to 9, (N − 1) times.
- Step 5: Assume the first element in the list as the smallest and store it in MIN and its position in POS.
- Step 6: Repeat Step 7 until the last element of the list.
- Step 7: Compare the next element in the list with the value of MIN. If it is found smaller, store it in MIN and its position in POS.
- Step 8: If the first element in the unsorted list and the value in MIN are not the same, then swap the first element with the element at position POS.
- Step 9: Revise the list by excluding the first element in the current list.
- Step 10: Print the sorted LIST.
- Step 11: Stop.
As with bubble sort, the repeated operations of identifying the smallest element and swapping it (steps 5 to 9) are grouped into a separate selection_sort() function.
# Traverse through all elements in the list def selection_sort(LIST, n): for i in range(n - 1): # Assume first element is the minimum min_index = i # Find index of smallest element in the remaining list for j in range(i + 1, n): if LIST[j] < LIST[min_index]: min_index = j # Swap min element with the first element of unsorted part LIST[i], LIST[min_index] = LIST[min_index], LIST[i] return LIST # Accept number of elements count = int(input("Enter how many numbers: ")) # Create an empty list ITEMS = [] # Accept n numbers from the user for i in range(count): num = int(input(f"Enter number {i+1}: ")) ITEMS.append(num) # Display the list print("Original list:", ITEMS) # Display the sorted list print("Sorted list:", selection_sort(ITEMS, count))
Enter how many numbers: 5 Enter number 1: 78 Enter number 2: 45 Enter number 3: 97 Enter number 4: 34 Enter number 5: 67 Original list: [78, 45, 97, 34, 67] Sorted list: [34, 45, 67, 78, 97]
Bubble sort vs Selection sort
Bubble sort repeatedly compares and swaps adjacent pairs as it moves through the list, so several swaps can happen within a single pass. Selection sort instead scans the entire unsorted portion first to find the overall smallest value, and performs at most one swap per pass.
Sorting Using Built-in Functions
Even though it is important to understand the algorithms behind sorting, Python provides two built-in tools for quick, efficient sorting: sort() and sorted().
(a) sort() Function
The built-in function sort() arranges the elements of a list in place — it changes the original list instead of creating a new one, and works only with lists. By default it sorts in ascending order; pass reverse=True for descending order.
Apart from numbers, sort() can be used on lists of strings, or any data type that supports comparison. By default, strings are sorted alphabetically. The key parameter specifies a function that determines the sorting criteria — for example, sorting by word length with key=len.
(b) sorted() Function
This built-in function returns a new sorted list from the elements of literal collections such as list, tuple or string — it does not modify the original collection. Like sort(), it also accepts reverse=True and key=len.
sort() modifies in place
Works only on lists, changes the original list, and returns None — never assign the result of list.sort() back to a variable.
sorted() returns a copy
Works on any iterable (list, tuple, string), leaves the original untouched, and returns a brand-new sorted list.
Even though Python provides sort() and sorted() for quick and efficient sorting, it is important to study the algorithms behind these operations. Learning bubble sort and selection sort helps you understand how data is processed, how efficiency is measured, and why certain methods perform better in specific situations.
Searching
Searching is the process of finding the location of a given element within a collection of data, such as a list, array, or database. It helps determine whether a particular item is present and, if present, its location.
Linear Search
Each element is checked one by one, in order, until the target is found or the list ends. Simple and convenient for small lists — already covered in Chapter 9.
Binary Search
Works efficiently only on sorted elements, repeatedly dividing the search space in half. Far fewer comparisons than linear search on large lists.
Binary Search
Binary search is an efficient searching technique that uses the minimum number of comparisons to locate an element in a sorted list. It checks the middle element — if it matches, the search ends; if the search value is smaller, it continues in the first half; if larger, it continues in the second half.
Algorithm for Binary Search
- Step 1: Start.
- Step 2: Accept a value in N as the number of elements of the list.
- Step 3: Accept N elements into the list named LIST in sorted order.
- Step 4: Accept the value to be searched in the variable ITEM.
- Step 5: Set search location, LOC = -1.
- Step 6: Store the position of the first element of the list in FIRST and position of the last element in LAST.
- Step 7: Repeat Steps 8 to 12 while (FIRST <= LAST).
- Step 8: Find the middle position using (FIRST + LAST)/2 and store it in MIDDLE.
- Step 9: Compare the search value in ITEM with the element at MIDDLE of the list.
- Step 10: If the MIDDLE element contains the search value, stop, display the position and go to Step 13.
- Step 11: If the search value is larger than the MIDDLE element, set FIRST = MIDDLE + 1.
- Step 12: If the search value is smaller than the MIDDLE element, set LAST = MIDDLE - 1.
- Step 13: If the value at LOC is less than 0, display "Not Found"; else display LOC + 1 as the position of the search value.
- Step 14: Stop.
As with the sorting algorithms, the repeated operations of locating the required element or narrowing the list to half its size are grouped into a separate binary_search() function.
# Initialize variables def binary_search(LIST, item, n): low = 0 high = n - 1 LOC = -1 LIST.sort() # Perform binary search while low <= high: mid = (low + high) // 2 if LIST[mid] == item: LOC = mid + 1 # Record position break elif item > LIST[mid]: low = mid + 1 # Search right half else: high = mid - 1 # Search left half # Display the location if LOC == -1: return None else: return LOC # Accept number of elements count = int(input("Enter how many numbers: ")) ITEMS = [] for i in range(count): num = float(input(f"Enter number {i+1}: ")) ITEMS.append(num) print("Number list:", ITEMS) # Accept item to search search_item = float(input("Enter the element to search: ")) pos = binary_search(ITEMS, search_item, count) if pos is None: print("Element not found") else: print("Element found at position ", pos)
Enter how many numbers: 5 Enter number 1: 23 Enter number 2: 34 Enter number 3: 43 Enter number 4: 46 Enter number 5: 49 Number list: [23.0, 34.0, 43.0, 46.0, 49.0] Enter the element to search: 46 Element found at position 4
Recursive Binary Search
Binary search is a good example of a problem that repeats in smaller, similar patterns — making it a natural fit for recursion. The algorithm examines the middle element; if the search value is smaller, it recursively searches the first half, and if larger, it recursively searches the second half.
def bsearch_recursive(arr, low, high, item):
if low > high:
return -1 # Element not found
mid = (low + high) // 2
if arr[mid] == item:
return mid + 1 # Return position
elif item > arr[mid]:
return bsearch_recursive(arr, mid + 1, high, item) # Right half
else:
return bsearch_recursive(arr, low, mid - 1, item) # Left half
# Accept number of elements
n = int(input("Enter how many numbers: "))
LIST = []
for i in range(n):
num = float(input(f"Enter number {i+1}: "))
LIST.append(num)
print("Number list:", LIST)
# Accept item to search
item = float(input("Enter the element to search: "))
# Perform recursive binary search
LOC = bsearch_recursive(LIST, 0, n - 1, item)
# Display result
if LOC == -1:
print("Element not found")
else:
print("Element found at position", LOC)
Binary Search Lab
Enter a comma-separated list (it will be sorted automatically) and a value to search for, then step through each iteration to watch FIRST, LAST and MIDDLE narrow down the answer.
Try a Binary Search
● liveSearching Using Built-in Functions
Searching in a list can also be performed in Python using the in operator and the built-in index() function.
(a) in Operator
in checks whether a value exists in a list, string, or tuple. If found, it returns True, otherwise False.
(b) index() Function
index() returns the index of the first occurrence of an element in a list. If the element is not in the list, it raises an exception (exception handling is covered in Class 12). Note that indexing starts from 0.
Convenience vs understanding
Although sort(), sorted(), index(), and the in operator make everyday tasks quick, understanding how bubble sort, selection sort and binary search work underneath strengthens problem-solving skills and prepares you for more advanced algorithmic concepts.
Quick Recap
Tap a question to reveal the answer.
Why does bubble sort get its name, and how many passes does it need for N elements?
Bubble sort repeatedly compares and swaps adjacent elements, so the largest unsorted element gradually "bubbles" towards the end of the list with each pass — just like a bubble rising to the surface. For a list of N elements, bubble sort requires (N − 1) passes, since the last pass leaves only two elements to compare.
In selection sort, why might a pass complete without any exchange taking place?
Each pass of selection sort finds the smallest element in the remaining unsorted portion and swaps it into the current position. If that smallest element is already sitting in the correct position, no exchange is needed — the pass still "completes," but no swap occurs, as seen in Pass 3 of the worked example.
What is the key structural difference between how bubble sort and selection sort make their swaps?
Bubble sort can perform many swaps within a single pass, since it swaps every out-of-order adjacent pair as it moves through the list. Selection sort performs at most one swap per pass — it first scans the entire unsorted section to find the minimum, and only then makes a single exchange.
What is the difference between list.sort() and sorted(list)?
sort() is a list method that sorts the list in place, modifying the original list and returning None — it only works on lists. sorted() is a built-in function that returns a new sorted list, leaving the original list, tuple, or string unchanged, and it works on any iterable.
Why must the list be sorted before applying binary search?
Binary search relies on comparing the search value with the middle element to decide whether to continue in the left half or the right half of the list. This "narrowing down" logic only works correctly if the elements are arranged in sorted order — on an unsorted list, the algorithm could eliminate the half that actually contains the target.
In binary search, what happens when FIRST becomes greater than LAST?
The condition FIRST <= LAST controls the search loop. Once FIRST exceeds LAST, it means the search range has been fully narrowed down without finding a match, so the loop ends and the search reports the element as "Not Found" (or returns -1/None depending on the implementation).
How does the recursive version of binary search differ from the iterative version?
The iterative version uses a while loop and updates low/high variables on each pass. The recursive version, bsearch_recursive(), instead calls itself with new low and high boundaries for the relevant half of the list, with the base case low > high stopping the recursion when the element is not found.
What is the difference between the in operator and the index() function when searching a list?
The in operator only checks whether a value exists in a list, string, or tuple, returning True or False. The index() function goes further and returns the position (starting from 0) of the first occurrence of that value — but it raises an exception if the value is not found.