Algorithms

Build a max-heap, then repeatedly move the largest element to the end — O(n log n), in place.

Version 1.2.0 · current Versions: 1.2.0 1.1.0 1.0.0

Implementations

Sign in to open in IDE Sign in with your Zerethon account to create your own copy of this sample.

Files

README.md
# Heap Sort

Zerethon Official Sample `heap-sort`, version 1.2.0, C (GCC 14).

- `heap_sort.c` / `heap_sort.h` — the algorithm, as shown in Zerethon Tools
- `main.c` — entry file: a short demonstration
- `test_heap_sort.c` — checks; set it as the entry file to run them

Run compiles the entry file together with every other `.c` file except other programs
(files whose name starts with `main` or `test_`).

This project is your own copy. Changing it never changes the official sample.
See the algorithm animated: https://tools.zerethon.com/heap-sort-visualizer
heap_sort.c
/* Heap Sort (Zerethon Official Sample: heap-sort 1.2.0).
   The algorithm as shown in Zerethon Tools. */
#include "heap_sort.h"

void sift_down(int a[], int lo, int hi) {
    int root = lo;
    while (2 * root + 1 <= hi) {
        int child = 2 * root + 1;
        if (child + 1 <= hi && a[child] < a[child + 1]) child++;
        if (a[root] < a[child]) {
            int t = a[root]; a[root] = a[child]; a[child] = t;
            root = child;
        } else return;
    }
}
void heap_sort(int a[], int n) {
    for (int i = n / 2 - 1; i >= 0; i--) sift_down(a, i, n - 1);
    for (int end = n - 1; end > 0; end--) {
        int t = a[0]; a[0] = a[end]; a[end] = t;
        sift_down(a, 0, end - 1);
    }
}
heap_sort.h
/* Heap Sort (Zerethon Official Sample: heap-sort 1.2.0). */
#ifndef HEAP_SORT_H
#define HEAP_SORT_H

void sift_down(int a[], int lo, int hi);
void heap_sort(int a[], int n);

#endif
main.c entry
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "heap_sort.h"

static void print_array(const char *label, const int *a, int n) {
    printf("%s[", label);
    for (int i = 0; i < n; i++) printf(i ? ", %d" : "%d", a[i]);
    printf("]\n");
}

static int compare(const void *x, const void *y) {
    return (*(const int *) x > *(const int *) y) - (*(const int *) x < *(const int *) y);
}

int main(void) {
    int numbers[] = {38, 27, 43, 3, 9, 82, 10, 27};
    int n = sizeof numbers / sizeof numbers[0];
    int result[sizeof numbers / sizeof numbers[0]], expected[sizeof numbers / sizeof numbers[0]];

    print_array("Before: ", numbers, n);
    memcpy(result, numbers, sizeof numbers);
    heap_sort(result, n);
    print_array("After:  ", result, n);
    memcpy(expected, numbers, sizeof numbers);
    qsort(expected, n, sizeof expected[0], compare);
    printf("Same as qsort(): %s\n", memcmp(result, expected, sizeof result) == 0 ? "true" : "false");
    return 0;
}
test_heap_sort.c
// Checks for heap_sort. To run them, set this file as the entry file
// (the ▶ button next to it in Files) and press Run.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "heap_sort.h"

static int compare(const void *x, const void *y) {
    return (*(const int *) x > *(const int *) y) - (*(const int *) x < *(const int *) y);
}

/* Deterministic pseudo-random integers in [-50, 49] (the same as the Python checks). */
static void numbers(long long seed, int count, int *out) {
    for (int i = 0; i < count; i++) {
        seed = (seed * 1103515245LL + 12345LL) % 2147483648LL;
        out[i] = (int) (seed % 100) - 50;
    }
}

static int checks = 0;

static int check(const int *c, int n) {
    int result[200], expected[200];
    memcpy(result, c, n * sizeof c[0]);
    memcpy(expected, c, n * sizeof c[0]);
    heap_sort(result, n);
    qsort(expected, n, sizeof expected[0], compare);
    checks++;
    if (memcmp(result, expected, n * sizeof c[0]) != 0) {
        fprintf(stderr, "heap_sort: wrong result for case %d (length %d)\n", checks, n);
        return 0;
    }
    return 1;
}

int main(void) {
    int ok = 1;
    ok &= check((int[]) {0}, 0);
    ok &= check((int[]) {1}, 1);
    ok &= check((int[]) {2, 1}, 2);
    ok &= check((int[]) {1, 2, 3}, 3);
    ok &= check((int[]) {3, 2, 1}, 3);
    ok &= check((int[]) {5, 1, 5, 1, 5}, 5);
    ok &= check((int[]) {-3, 0, -1, 2}, 4);
    int random[200];
    numbers(1, 10, random);
    ok &= check(random, 10);
    numbers(2, 50, random);
    ok &= check(random, 50);
    numbers(3, 200, random);
    ok &= check(random, 200);

    if (!ok) return 1;
    printf("All %d checks passed.\n", checks);
    return 0;
}

Source: Zerethon Official Sample. Algorithm as shown in the Zerethon Tools Heap Sort Visualizer.