<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=Huffman-Kodierung</id>
	<title>Huffman-Kodierung - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=Huffman-Kodierung"/>
	<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=Huffman-Kodierung&amp;action=history"/>
	<updated>2026-06-11T12:37:21Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Wikipedia (Deutsch) – Lokale Kopie</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki-de.moshellshocker.dns64.de/index.php?title=Huffman-Kodierung&amp;diff=26642&amp;oldid=prev</id>
		<title>imported&gt;Ulanwp: Fehlenden Sprachparameter eingefügt; 2 Datumsparameter konvertiert</title>
		<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=Huffman-Kodierung&amp;diff=26642&amp;oldid=prev"/>
		<updated>2026-03-18T15:48:25Z</updated>

		<summary type="html">&lt;p&gt;Fehlenden Sprachparameter eingefügt; 2 Datumsparameter konvertiert&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Die &amp;#039;&amp;#039;&amp;#039;Huffman-Kodierung&amp;#039;&amp;#039;&amp;#039; ist eine Form der [[Entropiekodierung]], die 1952 von [[David A. Huffman]] entwickelt und in der Abhandlung &amp;#039;&amp;#039;{{lang|en|A Method for the Construction of Minimum-Redundancy Codes}}&amp;#039;&amp;#039; publiziert wurde.&amp;lt;ref name=&amp;quot;orig_paper&amp;quot; /&amp;gt; Sie ordnet einer festen Anzahl an Quellsymbolen jeweils Codewörter mit variabler Länge zu. In der Informationstechnik ist sie ein [[Präfixcode]], der üblicherweise für verlustfreie Kompression benutzt wird. Wie bei anderen Entropiekodierungen werden häufiger vorkommende Zeichen mit weniger [[Bit|Bits]] repräsentiert als seltener vorkommende Zeichen.&lt;br /&gt;
&lt;br /&gt;
== Grundlagen ==&lt;br /&gt;
[[Datei:Huffman tree 2.svg|mini|330x330px|klasse=skin-invert-image|Der Huffman-Baum für den Beispielsatz &amp;quot;&amp;#039;&amp;#039;this is an example of a huffman tree&amp;#039;&amp;#039;&amp;quot;]]&lt;br /&gt;
Um Daten möglichst [[Redundanz (Informationstheorie)|redundanzfrei]] darzustellen, müssen die [[Symbol (Nachrichtentechnik)|Quellsymbole]] mit [[Code]]wörtern unterschiedlicher [[Wortlänge]]n kodiert werden. Die Länge der Codewörter entspricht dabei idealerweise ihrem [[Informationsgehalt]]. Um einen Code auch wieder eindeutig dekodieren zu können, muss er die [[Kraftsche Ungleichung]] erfüllen und zusätzlich noch &amp;#039;&amp;#039;[[Präfix-Code|präfixfrei]]&amp;#039;&amp;#039; sein, d. h., kein Codewort darf der Beginn eines anderen sein.&lt;br /&gt;
&lt;br /&gt;
Die Grundidee ist, einen &amp;#039;&amp;#039;k&amp;#039;&amp;#039;-nären Wurzelbaum (ein [[Baum (Graphentheorie)|Baum]] mit jeweils &amp;#039;&amp;#039;k&amp;#039;&amp;#039; Kindern je Knoten) für die Darstellung des Codes zu verwenden. In diesem sog. &amp;#039;&amp;#039;Huffman-Baum&amp;#039;&amp;#039; stehen die Blätter für die zu kodierenden Zeichen, während der Pfad von der Wurzel zum Blatt das Codesymbol bestimmt. Im Gegensatz zur [[Shannon-Fano-Kodierung]] wird der Baum dabei von den Blättern zur Wurzel ({{enS|&amp;#039;&amp;#039;[[bottom-up]]&amp;#039;&amp;#039;}}) erstellt.&lt;br /&gt;
&lt;br /&gt;
Dieser [[Baum (Datenstruktur)|Baum]] kann mit einem [[Heap (Datenstruktur)|Heap]] und einer [[Vorrangwarteschlange]] implementiert werden.&amp;lt;ref&amp;gt;David Wagner, University of California, Berkeley: [https://people.eecs.berkeley.edu/~daw/teaching/cs170-s03/Notes/lecture16.pdf Data Compression via Huffman Coding]&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Northeastern University: [https://www.ccs.neu.edu/home/vkp/2510-sp11/Labs/Lab11/lab11.pdf Priority Queue; Heapsort; Huffman Code]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Unterschied zum [[Morsecode]] benötigt man bei einer Huffman-Codierung keine Trennzeichen. Eine Trennung der Codewörter ist nicht notwendig, da die Codierung präfixfrei ist. Dadurch ist kein Codewort Anfang eines anderen Codewortes.&lt;br /&gt;
&lt;br /&gt;
Der bei der Huffman-Kodierung gewonnene Baum liefert garantiert eine optimale und präfixfreie Kodierung. D. h., es existiert kein symbolbezogenes Kodierverfahren, das einen kürzeren Code generieren könnte, wenn die Auftrittswahrscheinlichkeiten der Symbole bekannt sind.&lt;br /&gt;
&lt;br /&gt;
== Geschichte ==&lt;br /&gt;
Im Jahre 1951 hatten [[David A. Huffman]] und seine Klassenkameraden am [[Massachusetts Institute of Technology|MIT]] im Kurs Informationstheorie die Wahl zwischen einer Seminararbeit und einer Abschlussprüfung. Die [[Seminararbeit]], betreut von Professor [[Robert Fano|Robert M. Fano]], sollte die Findung des effizientesten binären Codes thematisieren. Huffman, der nicht in der Lage war, die Effizienz eines Codes zu beweisen, war nur knapp vor dem Entschluss, aufzugeben und sich für die Abschlussprüfung vorzubereiten, als er auf die Idee stieß, einen frequenzsortierten [[Binärbaum]] zu verwenden, und somit in kürzester Zeit jene Methode als effizienteste beweisen konnte.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise übertraf Huffman seinen Professor Fano, der gemeinsam mit dem Begründer der [[Informationstheorie]] [[Claude Shannon]] einen ähnlichen Code entwickelte. Indem Huffman den Baum von unten nach oben anstatt von oben nach unten erstellte, vermied er die größte Schwachstelle der suboptimalen [[Shannon-Fano-Kodierung]].&amp;lt;ref&amp;gt;[http://www.huffmancoding.com/my-uncle/scientific-american Profil: David A. Huffman]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Algorithmus ==&lt;br /&gt;
[[Datei:Huffman coding visualisation.svg|mini|360x360px|klasse=skin-invert-image|Veranschaulichung einer Huffman-Kodierung. Das Quellalphabet ist &amp;lt;math&amp;gt;X := \{ \_, A, B, C, D, E \}&amp;lt;/math&amp;gt; und das Codealphabet ist &amp;lt;math&amp;gt;C := \{ 0, 1 \}&amp;lt;/math&amp;gt;. Schritt 1 zeigt den Originaltext. Die Schritte 2 bis 6 erzeugen den [[Baum (Graphentheorie)|Baum]]. Der fertige Baum in Schritt 6 wird durchlaufen, um das Codebuch zu erzeugen. Schritt 7 zeigt das Codebuch und Schritt 8 den codierten Text.]]&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Definitionen&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039; ist das Quellalphabet – der Zeichenvorrat, aus dem die Quellsymbole bestehen&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;p_x&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039; ist die [[A-priori-Wahrscheinlichkeit]] und relative Häufigkeit des Symbols &amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039; ist das Codealphabet – der Zeichenvorrat, aus dem die Codewörter bestehen&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039; ist die [[Mächtigkeit (Mathematik)|Mächtigkeit]] &amp;lt;math&amp;gt;\vert C \vert&amp;lt;/math&amp;gt; des Codealphabetes &amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039; – die Anzahl der verschiedenen Zeichen&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Erzeugen des Baumes&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Ermittle für jedes Quellsymbol die [[relative Häufigkeit]], d. h., zähle, wie oft jedes Zeichen vorkommt, und teile durch die Anzahl aller Zeichen.&lt;br /&gt;
* Erstelle für jedes Quellsymbol einen einzelnen [[Knoten (Graphentheorie)|Knoten]] (die einfachste Form eines Baumes) und notiere im Knoten die Häufigkeit.&lt;br /&gt;
* Wiederhole die folgenden Schritte so lange, bis nur noch ein einziger [[Baum (Graphentheorie)|Baum]] übrig ist:&lt;br /&gt;
** Wähle &amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039; (Teil-)Bäume mit den &amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039; geringsten Häufigkeiten in deren Wurzel (diese Wahl ist im Allgemeinen nicht eindeutig).&lt;br /&gt;
** Fasse diese &amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039; Bäume zu einem neuen (Teil-)Baum zusammen.&lt;br /&gt;
** Notiere die Summe der Häufigkeiten in der Wurzel.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Konstruktion des [[Codebuch|Codebuchs]]&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Ordne jedem Kind eines Knotens eindeutig ein Zeichen aus dem Codealphabet zu.&lt;br /&gt;
* Lies für jedes Quellsymbol (Blatt im [[Baum (Graphentheorie)|Baum]]) das Codewort aus:&lt;br /&gt;
** Beginne an der Wurzel des Baums.&lt;br /&gt;
** Die Codezeichen auf den [[Kante (Graphentheorie)|Kanten]] des [[Pfad (Graphentheorie)|Pfades]] von oben nach unten ergeben das zugehörige Codewort.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Kodierung&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Lies ein Quellsymbol ein.&lt;br /&gt;
* Ermittle das zugehörige Codewort aus dem Codebuch.&lt;br /&gt;
* Gib das Codewort aus.&lt;br /&gt;
&lt;br /&gt;
=== Mittlere Wortlänge ===&lt;br /&gt;
Die mittlere Länge eines Codeworts kann auf drei Arten berechnet werden.&lt;br /&gt;
&lt;br /&gt;
* Über die gewichtete Summe der Codewortlängen:&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;math&amp;gt;\overline l = \sum_{x \in X} p_x l_x&amp;lt;/math&amp;gt;  Die Summe aus der Anzahl der Schritte im Baum multipliziert mit der Häufigkeit eines Symbols.&lt;br /&gt;
&lt;br /&gt;
* Indem man die Auftrittswahrscheinlichkeiten an allen &amp;#039;&amp;#039;Zwischen&amp;#039;&amp;#039;knoten des Huffman-Baums summiert.&lt;br /&gt;
* Bei ausschließlich gleicher Häufigkeit  der zu codierenden Elemente ist die mittlere Länge&lt;br /&gt;
:: &amp;lt;math&amp;gt; l = \log_2 \ m&amp;lt;/math&amp;gt; mit &amp;lt;math&amp;gt;m \in N&amp;lt;/math&amp;gt; als Anzahl der zu codierenden Elemente.&lt;br /&gt;
&lt;br /&gt;
=== Beispiele ===&lt;br /&gt;
[[Datei:Huffman tree 1.svg|mini|hochkant=1.5|klasse=skin-invert-image|Ein Huffman-Baum. Die Wurzel des Baumes befindet sich rechts, die Blätter links.]]&lt;br /&gt;
Das Quellalphabet sei &amp;lt;math&amp;gt;X := \{ a, b, c, d \}&amp;lt;/math&amp;gt;. Als Codealphabet wählen wir den [[Binärcode]] &amp;lt;math&amp;gt;C := \{ 0, 1 \}&amp;lt;/math&amp;gt; und &amp;lt;math&amp;gt;m = \vert C \vert = 2&amp;lt;/math&amp;gt;. Der Text &amp;lt;math&amp;gt;aababcabcd&amp;lt;/math&amp;gt; soll komprimiert werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst werden die [[Relative Häufigkeit|relativen Häufigkeiten]] bestimmt:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
p_a &amp;amp;= 0{,}4 \\&lt;br /&gt;
p_b &amp;amp;= 0{,}3 \\&lt;br /&gt;
p_c &amp;amp;= 0{,}2 \\&lt;br /&gt;
p_d &amp;amp;= 0{,}1&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es wird ein Huffman-Baum konstruiert und anschließend die Codewörter an den Kanten eingetragen (siehe Bild rechts).&lt;br /&gt;
&lt;br /&gt;
Daraus ergibt sich folgendes Codebuch:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
a &amp;amp;\rightarrow 1 \\&lt;br /&gt;
b &amp;amp;\rightarrow 01 \\&lt;br /&gt;
c &amp;amp;\rightarrow 001 \\&lt;br /&gt;
d &amp;amp;\rightarrow 000&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit diesem Codebuch wird der ursprüngliche Text kodiert:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Originaltext&amp;#039;&amp;#039;&amp;#039; || a || a || b  || a || b  || c   || a || b  || c   || d&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Kodierter Text&amp;#039;&amp;#039;&amp;#039; || 1 || 1 || 01 || 1 || 01 || 001 || 1 || 01 || 001 || 000&lt;br /&gt;
|}&lt;br /&gt;
Diese Huffman-Kodierung kodiert jedes Symbol mit durchschnittlich &amp;lt;math&amp;gt;\overline l = 0{,}4 \cdot 1 + 0{,}3 \cdot 2 + 0{,}2 \cdot 3 + 0{,}1 \cdot3 = 0{,}4 + 0{,}6 + 0{,}6 + 0{,}3 = 1{,}9&amp;lt;/math&amp;gt; Bit. Das ist die mittlere Codewortlänge. Bei einer naiven [[Kodierung]] würde jedes der 4 Symbole mit &amp;lt;math&amp;gt;\log_2(4) = 2&amp;lt;/math&amp;gt; Bit kodiert.&lt;br /&gt;
&lt;br /&gt;
Die [[Entropie (Informationstheorie)|Entropie]] liegt bei&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
H(X) &amp;amp;= -(0{,}4 \cdot \log_2(0{,}4) + 0{,}3 \cdot \log_2(0{,}3) + 0{,}2 \cdot \log_2(0{,}2) + 0{,}1 \cdot \log_2(0{,}1)) \\&lt;br /&gt;
     &amp;amp;\approx 1{,}846&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bit je Symbol. Dadurch, dass der [[Informationsgehalt]] je Quellsymbol keine [[ganze Zahl]] ist, verbleibt bei der Kodierung eine Rest-Redundanz.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Huffman_tree_2.svg|rechts|rahmenlos|330x330px|klasse=skin-invert-image]]&lt;br /&gt;
Für den Beispielsatz &amp;quot;&amp;#039;&amp;#039;this is an example of a huffman tree&amp;#039;&amp;#039;&amp;quot; ist das Quellalphabet &amp;lt;math&amp;gt;X := \{\_,a,e,f,h,i,l,m,n,o,p,r,s,t,u,x\}&amp;lt;/math&amp;gt; gegeben, wobei _ in diesem Fall für das [[Leerzeichen]] steht. Aus den absoluten Häufigkeiten der Quellsymbole, die in den Blättern des rechts dargestellten Huffman-Baums stehen, ergibt sich folgendes Codebuch:&lt;br /&gt;
{|&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;absolute Häufigkeit&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;Zuordnung&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\_: 7 \\&lt;br /&gt;
a: 4 \\&lt;br /&gt;
e: 4 \\&lt;br /&gt;
f: 3 \\&lt;br /&gt;
h: 2 \\&lt;br /&gt;
i: 2 \\&lt;br /&gt;
l: 1 \\&lt;br /&gt;
m: 2 \\&lt;br /&gt;
n: 2 \\&lt;br /&gt;
o: 1 \\&lt;br /&gt;
p: 1 \\&lt;br /&gt;
r: 1 \\&lt;br /&gt;
s: 2 \\&lt;br /&gt;
t: 2 \\&lt;br /&gt;
u: 1 \\&lt;br /&gt;
x: 1 \\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
\_ &amp;amp;\rightarrow 111 \\&lt;br /&gt;
a &amp;amp;\rightarrow 010 \\&lt;br /&gt;
e &amp;amp;\rightarrow 000 \\&lt;br /&gt;
f &amp;amp;\rightarrow 1101 \\&lt;br /&gt;
h &amp;amp;\rightarrow 1010 \\&lt;br /&gt;
i &amp;amp;\rightarrow 1000 \\&lt;br /&gt;
l &amp;amp;\rightarrow 11001 \\&lt;br /&gt;
m &amp;amp;\rightarrow 0111 \\&lt;br /&gt;
n &amp;amp;\rightarrow 0010 \\&lt;br /&gt;
o &amp;amp;\rightarrow 00110 \\&lt;br /&gt;
p &amp;amp;\rightarrow 10011 \\&lt;br /&gt;
r &amp;amp;\rightarrow 11000 \\&lt;br /&gt;
s &amp;amp;\rightarrow 1011 \\&lt;br /&gt;
t &amp;amp;\rightarrow 0110 \\&lt;br /&gt;
u &amp;amp;\rightarrow 00111 \\&lt;br /&gt;
x &amp;amp;\rightarrow 10010 \\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|}&lt;br /&gt;
Mit diesem Codebuch wird der Beispielsatz kodiert:&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Originaltext&amp;#039;&amp;#039;&amp;#039; || t || h || i  || s || _  || i   || s || _  || a   || n&lt;br /&gt;
|_&lt;br /&gt;
|e&lt;br /&gt;
|x&lt;br /&gt;
|a&lt;br /&gt;
|m&lt;br /&gt;
|p&lt;br /&gt;
|l&lt;br /&gt;
|e&lt;br /&gt;
|_&lt;br /&gt;
|o&lt;br /&gt;
|f&lt;br /&gt;
|_&lt;br /&gt;
|a&lt;br /&gt;
|_&lt;br /&gt;
|h&lt;br /&gt;
|u&lt;br /&gt;
|f&lt;br /&gt;
|f&lt;br /&gt;
|m&lt;br /&gt;
|a&lt;br /&gt;
|n&lt;br /&gt;
|_&lt;br /&gt;
|t&lt;br /&gt;
|r&lt;br /&gt;
|e&lt;br /&gt;
|e&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Kodierter Text&amp;#039;&amp;#039;&amp;#039; || 0110 || 1010 || 1000 || 1011 || 111 || 1000 || 1011 || 111 || 010 || 0010&lt;br /&gt;
|111&lt;br /&gt;
|000&lt;br /&gt;
|10010&lt;br /&gt;
|010&lt;br /&gt;
|0111&lt;br /&gt;
|10011&lt;br /&gt;
|11001&lt;br /&gt;
|000&lt;br /&gt;
|111&lt;br /&gt;
|00110&lt;br /&gt;
|1101&lt;br /&gt;
|111&lt;br /&gt;
|010&lt;br /&gt;
|111&lt;br /&gt;
|1010&lt;br /&gt;
|00111&lt;br /&gt;
|1101&lt;br /&gt;
|1101&lt;br /&gt;
|0111&lt;br /&gt;
|010&lt;br /&gt;
|0010&lt;br /&gt;
|111&lt;br /&gt;
|0110&lt;br /&gt;
|11000&lt;br /&gt;
|000&lt;br /&gt;
|000&lt;br /&gt;
|}&lt;br /&gt;
Diese Huffman-Kodierung kodiert jedes Symbol des Beispielsatzes (insgesamt 36 Zeichen) mit durchschnittlich&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\overline l = \tfrac{1}{36} \cdot (7 \cdot 3 + 4 \cdot 3 + 4 \cdot 3 + 3 \cdot 4 + 2 \cdot 4 + 2 \cdot 4 + 1 \cdot 5 + 2 \cdot 4 + 2 \cdot 4 + 1 \cdot 5 + 1 \cdot 5 + 1 \cdot 5 + 2 \cdot 4 + 2 \cdot 4 + 1 \cdot 5 + 1 \cdot 5) = \tfrac{1}{36} \cdot 135 = 3{,}75&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bit. Das ist die mittlere Codewortlänge. Bei einer naiven [[Kodierung]] würde jedes der 16 Symbole mit &amp;lt;math&amp;gt;\log_2(16) = 4&amp;lt;/math&amp;gt; Bit kodiert.&lt;br /&gt;
&lt;br /&gt;
== Dekodierung ==&lt;br /&gt;
Zur Dekodierung eines Huffman-kodierten Datenstroms ist beim klassischen Verfahren das im Kodierer erstellte Codebuch notwendig. Grundsätzlich wird dabei umgekehrt als im Kodierungsschritt vorgegangen. Der Huffman-Baum wird im Dekodierer wieder aufgebaut und mit jedem eingehenden [[Bit]] – ausgehend von der Wurzel – der entsprechende [[Pfad (Graphentheorie)|Pfad]] im [[Baum (Graphentheorie)|Baum]] abgelaufen, bis man an einem Blatt ankommt. Dieses Blatt ist dann das gesuchte Quellsymbol und man beginnt mit der Dekodierung des nächsten Symbols wieder an der Wurzel.&lt;br /&gt;
&lt;br /&gt;
=== Beispiel ===&lt;br /&gt;
[[Datei:Huffman_tree_1.svg|rechts|rahmenlos|klasse=skin-invert-image]]&lt;br /&gt;
Der Dekodierer hat das Codebuch&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
a &amp;amp;\rightarrow 1 \\&lt;br /&gt;
b &amp;amp;\rightarrow 01 \\&lt;br /&gt;
c &amp;amp;\rightarrow 001 \\&lt;br /&gt;
d &amp;amp;\rightarrow 000&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und die empfangene Nachricht 1101101001101001000.&lt;br /&gt;
&lt;br /&gt;
Jetzt wird für jedes empfangene Bit ausgehend von der Wurzel der Pfad im Baum abgelaufen, bis ein Blatt erreicht wurde (siehe Abbildung). Sobald ein Blatt erreicht wurde, speichert der Dekodierer das Symbol des Blattes und beginnt wieder bei der Wurzel, bis das nächste Blatt erreicht wird. Daraus ergibt sich der dekodierte Text:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Kodierter Text&amp;#039;&amp;#039;&amp;#039;|| 1 || 1 || 01 || 1 || 01 || 001 || 1 || 01 || 001 || 000&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Dekodierter Text&amp;#039;&amp;#039;&amp;#039;|| a || a || b  || a || b  || c   || a || b  || c   || d&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
Die folgenden Beispiele in [[Pseudocode]] zeigen [[Funktion (Programmierung)|Funktionen]] für die Generierung der Huffman-Kodierung.&lt;br /&gt;
&lt;br /&gt;
=== Erzeugen des Baumes ===&lt;br /&gt;
Diese [[Funktion (Programmierung)|Funktion]] erzeugt einen Huffman Tree als [[Min-Heap]] und gibt einen [[Zeiger (Informatik)|Zeiger]] auf den Wurzelknoten zurück. Die [[Knoten (Graphentheorie)|Knoten]] des Min-Heap werden in einer [[Vorrangwarteschlange]] gespeichert.&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * left // linker Kindknoten&lt;br /&gt;
  * right // rechter Kindknoten&lt;br /&gt;
  * top // Elternknoten&lt;br /&gt;
  * minHeap // Vorrangwarteschlange für den Min-Heap&lt;br /&gt;
  */&lt;br /&gt;
  &amp;#039;&amp;#039;&amp;#039;function&amp;#039;&amp;#039;&amp;#039; createHuffmanTree(symbolList, frequencyList, symbolsCount)&lt;br /&gt;
  {&lt;br /&gt;
    // Fügt die Knoten mit Symbol und Häufigkeit in die Vorrangwarteschlange ein&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;foreach&amp;#039;&amp;#039;&amp;#039; (symbol in symbolList)&lt;br /&gt;
    {&lt;br /&gt;
        Knoten mit Symbol und Häufigkeit in minHeap einfügen&lt;br /&gt;
    }&lt;br /&gt;
    // Der HuffmanTree wird schrittweise erzeugt, bis sich alle Knoten einem Baum befinden und nur noch der Wurzelknoten in der Vorrangwarteschlange ist&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;while&amp;#039;&amp;#039;&amp;#039; (die Anzahl der Knoten in minHeap ist nicht 1) // Solange die Anzahl der Knoten in der Vorrangwarteschlange nicht 1 ist&lt;br /&gt;
    {&lt;br /&gt;
        // Entfernt die zwei Knoten mit der kleinsten Häufigkeit aus der Vorrangwarteschlange&lt;br /&gt;
        left := minHeap.top()&lt;br /&gt;
        minHeap.pop()&lt;br /&gt;
        right := minHeap.top()&lt;br /&gt;
        minHeap.pop()&lt;br /&gt;
        Erzeuge einen neuen inneren Knoten top mit der Summe der Häufigkeiten der zwei Knoten left-&amp;gt;frequency und right-&amp;gt;frequency&lt;br /&gt;
        // Fügt die zwei Knoten mit der kleinsten Häufigkeit als linken und rechten Kindknoten des neuen inneren Knoten in den Baum ein&lt;br /&gt;
        top-&amp;gt;left := left&lt;br /&gt;
        top-&amp;gt;right := right&lt;br /&gt;
        minHeap.push(top) // Fügt den neuen Knoten in die Vorrangwarteschlange ein&lt;br /&gt;
    }&lt;br /&gt;
    return minHeap.top() // Gibt einen Zeiger auf den Wurzelknoten zurück&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== Erzeugen des Codebuchs ===&lt;br /&gt;
Diese [[Rekursive Programmierung|rekursive]] [[Funktion (Programmierung)|Funktion]] erzeugt das [[Codebuch]] für die Huffman-Kodierung, indem sie jedem Symbol des Quellalphabet ein [[Binärcode|binäres]] Codewort als [[Zeichenkette]] zuordnet.&lt;br /&gt;
 /**&lt;br /&gt;
  * dictionary // [[Zuordnungstabelle]] für das Codebuch&lt;br /&gt;
  */&lt;br /&gt;
  // Diese rekursive Funktion erzeugt das Codebuch für die Huffman-Kodierung und speichert es in der Variable dictionary&lt;br /&gt;
  &amp;#039;&amp;#039;&amp;#039;function&amp;#039;&amp;#039;&amp;#039; createDictionary(node, codeword, dictionary)&lt;br /&gt;
  {&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;if&amp;#039;&amp;#039;&amp;#039; (der Knoten ist node ist leer)&lt;br /&gt;
    {&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;return&amp;#039;&amp;#039;&amp;#039;; // [[Abbruchbedingung]], wenn kein linker oder rechter Teilbaum vorhanden ist&lt;br /&gt;
    }&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;if&amp;#039;&amp;#039;&amp;#039; (node-&amp;gt;symbol is kein innerer Knoten, also ein Blatt) // Wenn der Knoten kein innerer Knoten, also ein Blatt ist&lt;br /&gt;
    {&lt;br /&gt;
        dictionary.insert(node-&amp;gt;symbol, codeword); // Fügt die Kombination aus Symbol und Codewort dem Codebuch hinzu&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;return&amp;#039;&amp;#039;&amp;#039;; // Verlässt die Funktion&lt;br /&gt;
    }&lt;br /&gt;
    createDictionary(node-&amp;gt;left, concat(codeword, &amp;quot;0&amp;quot;), dictionary) // Rekusiver Aufruf für den linken Teilbaum, das Codesymbol 0 für die linke Kante wird angefügt&lt;br /&gt;
    createDictionary(node-&amp;gt;right, concat(codeword, &amp;quot;1&amp;quot;), dictionary) // Rekusiver Aufruf für den rechten Teilbaum, das Codesymbol 1 für die rechte Kante wird angefügt&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Optimalität ==&lt;br /&gt;
Für mittlere Codewortlänge &amp;lt;math&amp;gt;\overline l&amp;lt;/math&amp;gt; eines Huffman-Codes gilt&amp;lt;ref name=&amp;quot;Strutz&amp;quot;&amp;gt;Strutz: Bilddatenkompression, SpringerVieweg, 2009&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;\Eta(X) \leq \overline l \leq \Eta(X) + 1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das bedeutet, im Mittel benötigt jedes Codesymbol &amp;#039;&amp;#039;mindestens&amp;#039;&amp;#039; so viele Stellen wie sein [[Informationsgehalt]], höchstens jedoch eine mehr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\overline l = \Eta(X)&amp;lt;/math&amp;gt; gilt genau dann, wenn alle [[Wahrscheinlichkeit|Wahrscheinlichkeiten]] [[Zweierpotenz|Zweierpotenzen]] sind (&amp;lt;math&amp;gt;2^{-m_x}, \; m_x \in \mathbb{N}^+&amp;lt;/math&amp;gt;). In dem Fall sagt man, die Huffman-Kodierung sei &amp;#039;&amp;#039;optimal bezüglich der [[Entropie (Informationstheorie)|Entropie]]&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Fasst man &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; Quellsymbole zu einem großen Symbol &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; zusammen, so gilt für die mittleren Codesymbollängen &amp;lt;math&amp;gt;\overline l_y&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;\Eta_n(X) \leq \overline l_y \leq \Eta_n(X) + \frac{1}{n}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
das heißt, mit zunehmender Anzahl &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; gemeinsam kodierter Quellsymbole geht die mittlere Codewortlänge asymptotisch gegen die [[Entropie (Informationstheorie)|Entropie]] – die Huffman-Kodierung ist &amp;#039;&amp;#039;asymptotisch optimal&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Diese Optimalität der Huffman-Kodierung lässt sich mit [[Vollständige Induktion|vollständiger Induktion]] beweisen.&amp;lt;ref&amp;gt;University of California, Berkeley: [https://inst.eecs.berkeley.edu/~cs170/fa20/assets/notes/huffman.pdf Proof of Optimality of Huffman Coding]&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;University of Toronto: [https://www.cs.utoronto.ca/~brudno/csc373w09/huffman.pdf Proof of Optimality of Huffman Codes]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Laufzeit ==&lt;br /&gt;
Sei &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; die Anzahl der Zeichen des Originaltexts und &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; die Anzahl der verschiedenen Zeichen (meist deutlich weniger als Zeichen im Text). Die erste Anweisung, die die Häufigkeiten der Zeichen zählt, hat die asymptotische Laufzeit &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, da sie jedes Zeichen im Text beachten muss. Die [[for-Schleife]] iteriert über die verschiedenen Zeichen im Quellalphabet. Diese Schleife iteriert lediglich &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt; Mal und nicht &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; Mal. Die [[while-Schleife]] beginnt mit einer [[Vorrangwarteschlange]], die &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; Elemente enthält, und reduziert diese in jeder Iteration um ein Element. Sie iteriert also &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt; Mal. In jeder Iteration ruft sie zweimal die [[Funktion (Informatik)|Funktion]] &amp;#039;&amp;#039;pop&amp;#039;&amp;#039; und einmal die Funktion &amp;#039;&amp;#039;push&amp;#039;&amp;#039; auf, jeweils mit einer asymptotischen Laufzeit von &amp;lt;math&amp;gt;O(\log(d))&amp;lt;/math&amp;gt; bei Verwendung eines [[Heap (Datenstruktur)|Heaps]]. Alle anderen [[Operation (Informatik)|Operationen]] innerhalb der while-Schleife sind in konstanter [[Laufzeit (Informatik)|Laufzeit]] implementierbar. Die Laufzeit der while-Schleife ist also &amp;lt;math&amp;gt;O(d \cdot \log(d))&amp;lt;/math&amp;gt;. Damit ist die Gesamtlaufzeit für die Huffman-Kodierung &amp;lt;math&amp;gt;O(n + d \cdot \log(d))&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Justus Piater, Universität Innsbruck: [https://iis.uibk.ac.at/public/piater/courses/IIS/703010/notes/greedy/greedy.pdf Huffman Coding: Algorithmus und Analyse]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adaptive Huffman-Kodierung ==&lt;br /&gt;
&lt;br /&gt;
Die adaptive Huffman-Kodierung aktualisiert laufend den Baum. Der anfängliche Baum wird erzeugt, indem eine vorgegebene Wahrscheinlichkeitsverteilung für alle Quellsymbole angenommen wird (bei völliger Unkenntnis der Quelle eine [[Gleichverteilung]]). Mit jedem neuen Quellsymbol wird dieser aktualisiert, wodurch sich ggf. auch die Codesymbole ändern. Dieser Aktualisierungsschritt kann im Dekodierer nachvollzogen werden, so dass eine Übertragung des Codebuchs nicht nötig ist.&lt;br /&gt;
&lt;br /&gt;
Mit dieser Methode kann ein Datenstrom [[on-the-fly]] kodiert werden. Er ist jedoch erheblich anfälliger für Übertragungsfehler, da ein einziger Fehler zu einer – ab der Fehlerstelle – komplett falschen Dekodierung führt.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Arithmetisches Kodieren]]&lt;br /&gt;
* [[Bereichskodierung]]&lt;br /&gt;
* [[Shannon-Fano-Kodierung]]&lt;br /&gt;
* [[Tunstall-Kodierung]]&lt;br /&gt;
* [[Asymmetric Numeral Systems]]&lt;br /&gt;
* [[Context-Adaptive Binary Arithmetic Coding]]&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
* Thomas M. Cover, Joy A. Thomas: &amp;#039;&amp;#039;Elements of Information Theory&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* Freie Universität Berlin, Institut für Informatik: [https://www.inf.fu-berlin.de/lehre/WS11/infa/prefixcode.pdf Präfixcodes und der Huffman–Algorithmus]&lt;br /&gt;
* Freie Universität Berlin, Institut für Informatik: [https://www.inf.fu-berlin.de/lehre/WS12/ALP1/lectures/V16_ALPI_Huffman-Kodierung_2013.pdf Huffman-Kodierung]&lt;br /&gt;
* SwissEduc: [https://www.swisseduc.ch/informatik/daten/huffmann_kompression/docs/huffman.pdf Huffman-Code]&lt;br /&gt;
* LNTwww: [https://www.lntwww.de/Applets:Huffman-_und_Shannon-Fano-Codierung Huffman- und Shannon-Fano-Codierung]&lt;br /&gt;
* [https://www.javatpoint.com/huffman-coding-java Huffman Coding Java] (Codebeispiel in Java)&lt;br /&gt;
* Paul E. Black, National Institute of Standards and Technology: &amp;#039;&amp;#039;[http://xlinux.nist.gov/dads//HTML/huffmanCoding.html Huffman Coding]&amp;#039;&amp;#039;, Dictionary of Algorithms and Data Structures.&lt;br /&gt;
* [https://huffman.ooz.ie/ Huffman Tree Generator] (Web Application)&lt;br /&gt;
&lt;br /&gt;
== Einzelnachweise ==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;orig_paper&amp;quot;&amp;gt;{{cite journal |author=D. A. Huffman |date=1952-09 |title=A method for the construction of minimum-redundancy codes |journal=Proceedings of the I.R.E. |pages=1098–1101 |url=http://compression.ru/download/articles/huff/huffman_1952_minimum-redundancy-codes.pdf |format=PDF |language=en}}&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Kompressionsalgorithmus]]&lt;br /&gt;
[[Kategorie:Kodierungstheorie]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Ulanwp</name></author>
	</entry>
</feed>