PhoneBook — Algorithm Explorer

Learn sorting & searching algorithms — visualize every step!

Al-Farabi Kazakh National University · Algorithms & Data Structures

What is PhoneBook?

A console-based Python application for managing contacts — but with a twist! It implements 4 sorting algorithms and 4 search algorithms, allowing you to compare their performance side-by-side and learn how they work.

Data Structure: List of Dictionaries

Contacts are stored as a Python list of dictionaries: [ {'name': 'Alice', 'phone': '1234'}, ... ]. This simple structure makes it easy to demonstrate searching and sorting algorithms.

Features
Add Contact
Remove Contact
Edit Contact
View All Contacts
Linear Search
Binary Search
BST Search
Sort Comparison
CSV Save/Load
Statistics
Algorithm Compare
Complexity Guide
Big O Notation — Fastest to Slowest

Practical Impact (n = 1,000,000)

O(log n)20 operations  ·  O(n)1 million  ·  O(n log n)20 million  ·  O(n²)1 trillion!

Sorting Visualizer
Press Play to start

Bubble Sort — The Simplest

Repeatedly compares adjacent elements and swaps them if they're in the wrong order. Each pass "bubbles" the largest unsorted element to its correct position.

Time: O(n²) Space: O(1) Stable: Yes

Selection Sort — Predictable

Finds the minimum element repeatedly and places it at the beginning of the unsorted portion. Always O(n²) — no best case optimization.

Time: O(n²) Space: O(1) Stable: No

Merge Sort — Guaranteed Fast

Divides the array in half recursively, sorts each half, then merges them back together. Always O(n log n) — guaranteed performance regardless of input!

Time: O(n log n) Space: O(n) Stable: Yes

Quick Sort — Industry Standard

Picks a pivot, partitions elements around it, then recursively sorts partitions. Average O(n log n), worst O(n²). Most commonly used in practice!

Avg: O(n log n) Worst: O(n²) Space: O(log n)
Sorting Algorithm Comparison
Algorithm Best Average Worst Space Stable
Bubble Sort O(n) O(n²) O(n²) O(1)
Selection Sort O(n²) O(n²) O(n²) O(1)
Merge Sort O(n log n) O(n log n) O(n log n) O(n)
Quick Sort O(n log n) O(n log n) O(n²) O(log n)
When to Use What?
  • 1Small arrays — Bubble or Selection (simple, easy to understand)
  • 2Large arrays — Merge or Quick Sort (efficient O(n log n))
  • 3Stability needed — Merge Sort (maintains relative order)
  • 4Interviews & practice — Quick Sort (most commonly asked)
Core CRUD Operations
# Global list to store contacts
contacts = []

def add_contact(name, phone):
    """Add a new contact. Time Complexity: O(n)"""
    if not name or not phone:
        print("Error: Name and phone cannot be empty.")
        return False

    # Linear Search for duplicates - O(n)
    for contact in contacts:
        if contact['name'].lower() == name.lower():
            print(f"Error: Contact '{name}' already exists.")
            return False

    contacts.append({'name': name, 'phone': phone})
    return True

def remove_contact(name):
    """Remove a contact by name. Time Complexity: O(n)"""
    for i, contact in enumerate(contacts):
        if contact['name'].lower() == name.lower():
            contacts.pop(i)
            return True
    return False

def edit_contact(name, new_phone):
    """Edit a contact's phone number. Time Complexity: O(n)"""
    for contact in contacts:
        if contact['name'].lower() == name.lower():
            contact['phone'] = new_phone
            return True
    return False
All Functions — Time Complexity
FunctionComplexityDescription
add_contact()O(n)Linear search for duplicates
remove_contact()O(n)Linear search to find contact
edit_contact()O(n)Linear search to find contact
linear_search()O(n)Must check every contact
binary_search()O(log n)Requires sorted list
bubble_sort()O(n²)Two nested loops
selection_sort()O(n²)Find minimum repeatedly
merge_sort()O(n log n)Divide and conquer
quick_sort()O(n log n)Partition by pivot
load_from_file()O(n)Read n contacts
save_to_file()O(n)Write n contacts