Skip to content

refernandes/sorting_visualizer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SortViz — Sorting Algorithm Visualizer

Real-time step-by-step visualizer for sorting algorithms, built in C + Raylib.
Run up to four algorithms side-by-side, hear each comparison as a pitch-mapped tone, and control array size and speed live from a collapsible panel.


Screenshot

Screenshot do projeto


Features

9 algorithms Bubble, Selection, Insertion, Shell, Gnome, Cocktail Shaker, Merge, Quick, Heap
Multi-view 1, 2, or 4 simultaneous visualizations in the same window
Live controls Array size (8–512) and speed (1–32 steps/frame) via sliders
Sound Pitch-mapped sine tones — the higher the bar, the higher the note
Panel toggle Collapse/expand the side panel with the ◀ button or resize freely
Focus ring Click any view to focus it; stats and sound follow the focused view
Colour semantics Each bar state has a distinct vivid colour (see table below)
42 Norm All source files comply with École 42 Norminette v3

Dependencies

  • GCC with C11 support
  • Raylib 5.x installed system-wide
# Arch Linux
sudo pacman -S raylib

# Ubuntu / Debian
sudo apt install libraylib-dev

# macOS
brew install raylib

# From source (all platforms)
# https://github.com/raysan5/raylib

Build & Run

# Build and launch immediately
make run

# Build only
make

# Remove object files and binary
make clean

The Makefile compiles every src/*.c automatically — adding a new algorithm file requires no Makefile edits.

Custom Raylib path — if Raylib is not under /usr, pass RAYLIB_PATH:

make run RAYLIB_PATH=/usr/local

Controls

Input Action
Space Pause / Resume
R Shuffle and restart all views
1 Single-view mode
2 Two views side by side
4 Four views in a 2×2 grid
Click on any view Focus that view (panel stats + sound follow it)
Scroll wheel Scroll the algorithm list in the panel
◀ / ▶ button Toggle the side panel
Speed slider Steps executed per frame (1 = slow-motion, 32 = fast)
Array Size slider Number of elements (8 – 512)
⏸ / ▶ button Pause / Resume
button Shuffle & restart

Adding a New Algorithm

1. Scaffold the file

make new_algo NAME=radix_sort
# → creates src/radix_sort.c with the full boilerplate

2. Implement update()

Open src/radix_sort.c. The update function must advance exactly one logical step per call — the engine calls it speed times per frame automatically.

#include "common.h"

static void	update(t_sort_state *s)
{
    if (s->sorted)
        return ;
    /*
     * Use s->i, s->j as persistent cursors between frames.
     * Use s->aux[] as scratch space (e.g. temp values, stack).
     * Highlight up to 4 indices via s->hl[] / s->hl_count.
     * Use s->pivot_idx for a yellow pivot marker (-1 = off).
     */
    s->hl[0] = s->i;
    s->hl_count = 1;
    s->comparisons++;
    /* ... your swap / write logic ... */
    s->swaps++;
    /* Signal completion: */
    s->sorted = true;
    s->hl_count = 0;
}

void	register_radix_sort(void)
{
    t_algorithm	algo;

    algo.name       = "Radix Sort";
    algo.category   = "Non-comparison";
    algo.update     = update;
    algo.reset      = NULL;     /* or a custom reset fn if needed */
    algo.stable     = true;
    algo.complexity = "O(nk)";
    register_algorithm(algo);
}

3. Register in main.c

Add two lines to src/main.c:

/* 1. Forward declaration — top of main.c, with the others */
void	register_radix_sort(void);

/* 2. Call it — inside init_app(), with the other register_*() calls */
register_radix_sort();

The algorithm appears in the panel list immediately on the next make run.


t_sort_state Reference

typedef struct s_sort_state
{
    int     values[MAX_SIZE]; /* the array being sorted                    */
    int     size;             /* current length                            */
    int     i, j;            /* persistent cursors — survive between frames*/
    int     aux[MAX_SIZE];   /* scratch: temp array, index stack, flags…  */
    int     pivot_idx;       /* yellow marker; set to -1 when not in use  */
    bool    sorted;          /* set true when the algorithm is done       */
    long    comparisons;     /* increment on every key comparison         */
    long    swaps;           /* increment on every swap or write          */
    double  elapsed_ms;      /* available for timing; unused by engine    */
    int     speed;           /* steps/frame — read-only inside update()   */
    int     hl[4];           /* indices to highlight in red (up to 4)     */
    int     hl_count;        /* how many hl[] entries are active          */
}   t_sort_state;

Bar colour semantics

Constant Colour Meaning
COL_BAR_DEFAULT Indigo Idle, unsorted
COL_COMPARING Rose-red Active indices in hl[]
COL_SORTED Emerald Confirmed final position
COL_PIVOT Amber pivot_idx — Quick Sort pivot
COL_MIN Violet Current minimum — Selection Sort
COL_WRITE Sky-blue Write target — Radix / Counting Sort

Project Structure

sorting_visualizer/
├── include/
│   └── common.h          ← types, palette macros, full public API
├── src/
│   ├── main.c            ← window init, game loop, algorithm registry
│   ├── draw.c            ← DrawSortBars(), DrawInfoOverlay()
│   ├── ui.c              ← UiButton(), UiSlider(), DrawTxt(), SetAppFont()
│   ├── ui_misc.c         ← UiLabel(), UiSeparator(), UiTag()
│   ├── views.c           ← reset_view(), set_view_count(), view_bounds()
│   ├── loop.c            ← update_sorts(), handle_sound(), handle_input(), draw_frame()
│   ├── toolbar.c         ← top-bar rendering
│   ├── panel.c           ← side panel: algorithm list, scrollbar, controls
│   ├── panel_info.c      ← side panel: array-size and stats sections
│   ├── sound.c           ← sine-tone synthesis via Raylib Wave API
│   ├── bubble_sort.c
│   ├── selection_sort.c
│   ├── insertion_sort.c
│   ├── shell_sort.c
│   ├── gnome_sort.c
│   ├── cocktail_sort.c
│   ├── merge_sort.c
│   ├── quick_sort.c
│   └── heap_sort.c
└── Makefile

Frame data flow

game_loop()
 ├── update_sorts()     calls algo.update() × speed for each active view
 ├── handle_sound()     plays pitch-mapped tone for the focused view
 ├── handle_input()     keyboard shortcuts + mouse click / focus routing
 └── draw_frame()
      ├── DrawSortBars() × view_count   render bars + header per view
      ├── draw_dividers()               grid lines between split views
      ├── draw_panel()                  side panel (algo list, sliders, stats)
      └── draw_toolbar()                top bar (title, view buttons, speed)

École 42 — Norminette v3

The entire codebase follows Norminette v3 rules:

  • ≤ 25 lines per function body (excluding braces)
  • ≤ 5 functions per .c file (including static helpers)
  • ≤ 5 local variables per function
  • ≤ 4 parameters per function
  • No for loops — all iteration uses while
  • No switch, no ternary ?:
  • Declarations at the top of each block, before any instruction
  • Tab indentation, lines ≤ 80 characters
  • t_ prefix on all typedef structs

Suggested Roadmap

  • Radix Sort (LSD)
  • Counting Sort
  • Tim Sort
  • Bitonic Sort
  • Race mode — timer per algorithm, winner highlighted
  • Export comparison / swap metrics to CSV

About

An interactive sorting algorithms visualizer built in pure C for the Linux terminal. Analyzes algorithm complexity (Big O) in real-time.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors