Der Insertion-Sort-Algorithmus

Der Insertion-Sort-Algorithmus

🌐 Read in English
📅 2026-09-11 ✍ Andreas Wittmann đŸ‘ïž ... algorithm sorting computer-graphics

Bubble Sort sortiert, indem es wiederholt die gesamte Liste durchlĂ€uft und Nachbarn tauscht. Insertion Sort verfolgt einen anderen Ansatz: Er hĂ€lt vorne in der Liste einen sortierten Abschnitt und lĂ€sst ihn Element fĂŒr Element wachsen, wobei jeder neue Wert genau dort eingefĂŒgt wird, wo er hingehört — so, wie die meisten Menschen ein Blatt Spielkarten sortieren.

Die Idee

Insertion Sort betrachtet die Liste als zweigeteilt: einen sortierten PrĂ€fix am Anfang und den Rest. Zu Beginn besteht der sortierte PrĂ€fix nur aus dem ersten Element — ein einzelnes Element ist trivial "sortiert".

FĂŒr jedes folgende Element, den SchlĂŒssel, schiebt Insertion Sort es in den sortierten PrĂ€fix hinein: Es vergleicht den SchlĂŒssel von rechts nach links mit dem PrĂ€fix und schiebt jedes grĂ¶ĂŸere Element eine Position nach rechts, bis es die Stelle findet, an die der SchlĂŒssel gehört. Genau in die dabei entstehende LĂŒcke wird der SchlĂŒssel platziert. Danach ist der sortierte PrĂ€fix um eins gewachsen, und der Vorgang wiederholt sich mit dem nĂ€chsten Element.

Implementierung

#include "plot.hpp"
#include <stdlib.h>

const int N = 20;
int values[N];
int i = 1;     // index of the element currently being inserted
int k = -2;    // -2 = pick a new key, -1..i-1 = shifting comparison pointer
int key = 0;
bool done = false;
int tick = 0;

void setup() {
    PlotCanvas(640, 480);

    for (int n = 0; n < N; n++) {
        values[n] = n + 1;
    }

    srand(1);
    for (int n = N - 1; n > 0; n--) {
        int r = rand() % (n + 1);
        int tmp = values[n];
        values[n] = values[r];
        values[r] = tmp;
    }
}

void frame() {
    // Slow the animation down: one step every few calls to frame() instead
    // of one per call, so individual shifts stay visible.
    if (!done && ++tick >= 4) {
        tick = 0;

        if (k == -2) {
            if (i >= N) {
                done = true;
            } else {
                key = values[i];
                k = i - 1;
            }
        } else if (k >= 0 && values[k] > key) {
            values[k + 1] = values[k];
            k--;
        } else {
            values[k + 1] = key;
            i++;
            k = -2;
        }
    }

    PlotBackground(250, 250, 250);

    int activeIndex = (k == -2) ? i : (k + 1);
    int barWidth = plot_width / N;

    for (int idx = 0; idx < N; idx++) {
        if (!done && idx == activeIndex) {
            PlotColor(220, 60, 60);   // the key currently being inserted
        } else if (idx < i) {
            PlotColor(70, 170, 90);   // sorted prefix
        } else {
            PlotColor(30, 100, 200);  // not yet reached
        }

        int height = values[idx] * (plot_height - 20) / N;
        int x0 = idx * barWidth + 1;
        int x1 = x0 + barWidth - 2;
        int y0 = plot_height - height;
        int y1 = plot_height;
        PlotFilledRectangle(x0, y0, x1, y1);
    }
}
Open in full editor →

i markiert, wie weit der sortierte PrĂ€fix reicht; k lĂ€uft rĂŒckwĂ€rts durch ihn und vergleicht mit key, wobei Elemente nach rechts geschoben werden (values[k + 1] = values[k]), solange sie grĂ¶ĂŸer sind. Sobald k keine grĂ¶ĂŸeren Elemente mehr zum Schieben findet, wird key in die LĂŒcke geschrieben und i rĂŒckt vor. Wie beim Bubble-Sort-Sample fĂŒhrt frame() nur alle paar Aufrufe einen solchen Schritt aus, damit die einzelnen Verschiebungen sichtbar bleiben statt sofort durchzulaufen. Die Balkenfarben markieren dieselben drei ZustĂ€nde wie zuvor, nur mit anderer Bedeutung:

Schritt fĂŒr Schritt durchgerechnet

FĂŒr [5, 1, 4, 2, 8] beginnt der sortierte PrĂ€fix als nur [5]. Beim EinfĂŒgen von 1:

Schritt Vergleich schieben? Array
Start key = 1 — [5, 1, 4, 2, 8]
k=0 5 > 1 5 nach rechts schieben [5, 5, 4, 2, 8]
platzieren k = -1, nichts mehr zu vergleichen 1 einfĂŒgen [1, 5, 4, 2, 8]

Der PrĂ€fix ist jetzt [1, 5]. Beim nĂ€chsten EinfĂŒgen von 4 reicht eine Verschiebung (5 rĂŒckt nach rechts, 4 landet zwischen 1 und 5); das EinfĂŒgen von 2 braucht zwei Verschiebungen vorbei an 5 und 4; 8 braucht keine, da es bereits grĂ¶ĂŸer ist als alles im PrĂ€fix. Nach allen vier EinfĂŒgungen ist die Liste sortiert.

Warum er manchmal noch verwendet wird

Insertion Sort ist im schlechtesten Fall O(nÂČ), genau wie Bubble Sort — asymptotisch nicht besser. Aber zwei Eigenschaften halten ihn im praktischen Einsatz:

Er ist außerdem ein stabiles Sortierverfahren: Elemente, die als gleich verglichen werden, behalten ihre ursprĂŒngliche relative Reihenfolge, da ein SchlĂŒssel immer nur an strikt kleineren Elementen vorbeigeschoben wird. Bubble Sort teilt diese Eigenschaft; nicht jeder Sortieralgorithmus tut das.

Fazit

WĂ€hrend Bubble Sort die gesamte Liste immer wieder neu durchsucht, setzt Insertion Sort auf einen wachsenden sortierten Bereich und verrichtet genau die Arbeit, die nötig ist, um jedes neue Element dort einzufĂŒgen. Dieser Unterschied — asymptotisch irrelevant, da beide O(nÂČ) sind — macht in der Praxis viel aus, weshalb Insertion Sort, anders als Bubble Sort, auch heute noch in den Standard-Sortieralgorithmen auftaucht.