Есть переформулировка условия Фано, после которой оно перестаёт быть правилом, которое надо запоминать, и становится очевидным. Но сначала – про схему, на которой всё будет нарисовано. В учебнике она встречается впервые, а в следующем уроке, про алгоритм Хаффмана, будет работать всё время.
Дерево – схема из точек (узлов), соединённых линиями (рёбрами), устроенная так: есть одна выделенная точка – корень, и из корня в любой другой узел ведёт ровно один путь. Никаких развилок, которые потом сходятся обратно, и никаких замкнутых колец в дереве нет.
Рисуют деревья в информатике вверх ногами: корень сверху, ветви растут вниз. Дальше словарь такой:
- лист – узел, из которого вниз уже ничего не растёт, тупик ветви;
- внутренний узел – узел, из которого ветви идут дальше (корень тоже внутренний, если дерево не состоит из него одного);
- глубина узла – сколько рёбер надо пройти от корня до него.
Дерево называют двоичным, если из каждого узла вниз выходит не больше двух рёбер. Именно такое нам и нужно: битов ровно два.
Теперь соберём кодовое дерево. Из каждого узла проведём два ребра: влево – 0, вправо – 1. Тогда кодовое слово – это маршрут от корня, а символ ставится в ту точку, где маршрут заканчивается. Код 110 читается как «вправо, вправо, влево», и приводит он ровно в один узел – потому что путь от корня в дереве всегда единственный.
- Если все символы сидят в листьях, условие Фано выполняется автоматически: маршрут в тупик нельзя продолжить, а значит, он не может быть началом другого маршрута.
- Если символ оказался во внутреннем узле, через него проходят маршруты к другим символам – это и есть нарушение.
Отсюда правило, которым удобно проверять таблицу глазами: символы – только в листьях.
И здесь же видно, откуда берётся ограничение на жадность. Отдать короткий код 0 одному символу – значит забрать вместе с ним всю левую половину дерева. Бесплатных коротких кодов не бывает: за каждый платят удлинением остальных.