NetNado
  Найти на сайте:

Учащимся

Учителям



1. /_Методички/Мультимедиа-системы. Архитектура, стандарты, алгоритмы.pdf
2. /_Методички/Организация ЭВМ 2006.doc
3. /_Методички/Основы сетевых технологий.djvu
4. /_Методички/Программирование/Биные Деревья Поиска/2_01БДПоиска.doc
5. /_Методички/Программирование/Биные Деревья Поиска/2_02БинДП.doc
6. /_Методички/Программирование/Биные Деревья Поиска/2_03СлучайБДП.doc
7. /_Методички/Программирование/Деревья Хаффмана/1.doc
8. /_Методички/Программирование/Деревья Хаффмана/1_1ДХафф.doc
9. /_Методички/Программирование/Деревья Хаффмана/1_2_3_ДХафф.doc
10. /_Методички/Программирование/Деревья Хаффмана/1_4_ДХафф.doc
11. /_Методички/Программирование/Деревья Хаффмана/1_5_ДХафф.doc
12. /_Методички/Программирование/Деревья Хаффмана/1_6_7_ДХафф.doc
13. /_Методички/Программирование/Деревья Хаффмана/1_8ДХафф.doc
14. /_Методички/Программирование/Деревья Хаффмана/1_9ДХафф.doc
15. /_Методички/Программирование/Деревья Хаффмана/ДерХафф full.doc
16. /_Методички/Программирование/Деревья Хаффмана/КарлКлара.doc
17. /_Методички/Программирование/Деревья Хаффмана/Кодируется текст АБРАКАДАБРА.doc
18. /_Методички/Программирование/Динамические СД/00Титул.rtf
19. /_Методички/Программирование/Динамические СД/0Введение.rtf
20. /_Методички/Программирование/Динамические СД/1Списки.doc
21. /_Методички/Программирование/Динамические СД/2СтекОчДек1.rtf
22. /_Методички/Программирование/Динамические СД/3Деревья.rtf
23. /_Методички/Программирование/Динамические СД/4прим_лит.rtf
24. /_Методички/Программирование/Динамические СД/5оглавление.doc
25. /_Методички/Программирование/Динамические СД/Динамическое программирование - Задача о перемножении матриц.doc
26. /_Методички/Программирование/Пособие по разработке корректных программ/00Титул1_3.doc
27. /_Методички/Программирование/Пособие по разработке корректных программ/01Введение.rtf
28. /_Методички/Программирование/Пособие по разработке корректных программ/1АлгоритмЕвклида.doc
29. /_Методички/Программирование/Пособие по разработке корректных программ/2ОсновыАналитВерифПрогРовно.doc
30. /_Методички/Программирование/Пособие по разработке корректных программ/3ИндуктФункции.doc
31. /_Методички/Программирование/Пособие по разработке корректных программ/4Массивы.doc
32. /_Методички/Программирование/Пособие по разработке корректных программ/5Поиск.doc
33. /_Методички/Программирование/Пособие по разработке корректных программ/ОглавФонар.doc
34. /_Методички/Программирование/Пособие по разработке корректных программ/СписЛит&УслОбознач.doc
35. /_Методички/Сетевые технологии.pdf
36. /_Методички/Средства моделирования вычислительных сетей.pdf
37. /_Методички/Управление вычислительными сетями.pdf
Учебное пособие Редактор А. В. Крейцер Издательство спбгэту «лэти» 1 97376, С. Петербург, ул. Проф. Попова, 5
2. Деревья поиска Идеально сбалансированные бинарные деревья
2 Случайные бинарные деревья поиска
Абракадабра!, содержащий 12 символов, включая специальный символ !
Задача кодирования сообщений. Префиксные коды и деревья Пусть задан алфавит
1 Код Фано-Шеннона
1 Метод Хаффмана
1 Реализация алгоритмов кодирования
1 Доказательство оптимальности кода Хаффмана Лемма 1
1 Энтропийная оценка средней длины кода
1 Динамическое кодирование по Хаффману
Абракадабра!, содержащий 12 символов, включая специальный символ !
Абракадабра!, содержащий 12 символов, включая специальный символ !
А. Ю. Алексеев с. А. Ивановский д. В. Куликов
При обучении программированию особую трудность вызывает работа с динамическими структурами данных
2. стеки и очереди спецификация стека и очереди
3 Определения дерева, леса, бинарного дерева. Скобочное представление
Примечания и библиографические указания
Списки
Задача о порядке перемножения матриц
С. А. Ивановский разработкакорректныхпрограм м санкт-Петербург 2003
Программирования
Разработка, доказательство корректности и анализ алгоритма
2. основы аналитической верификации программ основные правила аналитической верификации программ
3. индуктивные функции на последовательностях
4. корректность программ при работе с массивами
5. поиск в массиве линейный поиск
Разработка, доказательство корректности
Шень А. Программирование: теоремы и задачи: Учеб пособие

скачать doc



1.5. Реализация алгоритмов кодирования
Рассмотрим реализацию алгоритмов кодирования Фано-Шеннона и Хаффмана. Для записи алгоритмов будем использовать псевдокод, основанный на языке Паскаль.

Для представления кодовых деревьев удобно использовать бинарные деревья с размеченными листьями. Эти деревья изоморфны рассмотренным в [*] иерархическим спискам. Их внутренние узлы не содержат иной информации, кроме ссылок на левое и правое поддеревья (деревья строго бинарные), а листья (внешние узлы) содержат собственно элементы базового типа. Рекурсивные типы данных, представляющие такие деревья, используют структуру размеченного объединения (записи с вариантами в языке Паскаль или структуру Union в языках C и C++). Определим для представления размеченного бинарного дерева типы данных
type TBT = Node;

Node = record

case Tag: (Inter, Leaf) of

Inter: (Left, Right: TBT);

Leaf: (Info: Num)

end {Node};
где Num = 0..nMax – тип данных для нумерации символов алфавита. Далее для типа TBT считаем определенными функции Null, Create, ConsTBT, LeftTBT, RightTBT, а также функцию MakeLeaf, создающую дерево из одного листа. При этом функция ConsTBT создает внутренний узел, т. е. узел типа Node с полем Tag = Inter, а функция MakeLeaf создает узел типа Node с полем Tag = Leaf.

Для представления двоичного кода используем абстрактный тип SeqB = Sequence of Bit, для которого определены соответствующие базовые функции, в том числе Null, Create, First, Rest, Postfix (см. [*], раздел 2). Функция-конструктор Postfix(Sb) дописывает бит b в конец последовательности S.

Первым рассмотрим алгоритм построения кода Фано-Шеннона. Вспомогательная процедура Middle разделяет набор символов (с учетом их весов) на две части, которым далее будут соответствовать левое и правое поддеревья. Входными параметрами процедуры Middle являются:

  1. упорядоченный по неубыванию массив весов w[1..n], имеющий тип w_vector = array [Num1] of weight, где Num1 = 1..nMax;

  2. индексы начала L и конца H сегмента массива w[1..n], соответствующего поддереву для группы символов от L до H;

  3. сумма весов сегмента .

Для описания выходных данных введем обозначения . Выходными параметрами процедуры Middle являются:

    1. индекс k, такой, что разность имеет минимальное по абсолютной величине значение;

    2. суммы весов и для выходного значения k.

При этом выполняется соотношение , а и используются далее при рекурсивном построении левого и правого поддеревьев.

Итак
procedure Middle ({in:}ww_vector; S: weight; L, H: Num;

{out:} var k: Num; var SL, SR: weight);

begin

SL := 0; SR:= S;

k := L – 1;

while SL < SR do

begin

k := k + 1;

SL := SL + w[k];

SR := SR  w[k]

end {while};

{ SL ≥ SR }

if SL ≥ SR + w[k] then

begin

k := k  1;

SL := SL  w[k];

SR := SR + w[k]

end {if}

end {Middle}
Отметим, что выход из цикла происходит при смене знака разности , затем если после выхода предыдущее значение abs(  ) было меньше, чем новое   , то k уменьшается на единицу, а и принимают предыдущие значения.

Следующая рекурсивная процедура F_Sh строит кодовое дерево b и коды Фано-Шеннона символов алфавита, размещаемые в глобальном массиве CodeFS. Параметр Code, в котором формируется код текущего узла дерева, используется как накапливающий.

Procedure F_Sh ( {in:} ww_vector; S: weight; L, H: Num; Code: SeqB;

{out:} var b: TBT);

{Global: CodeFS: array [Num] of SeqB}

begin

if L = H then

begin

b := MakeLeaf (L);

CodeFS[L] := Code

end

else

begin

Middle (w, S, L, H, k, SL, SR); {S = SL + SR }

{построить левое поддерево:}

F_Sh (w, SL, L, k, Postfix(Code, 0), bL);

{построить правое поддерево:}

F_Sh (w, SR, k + 1, H, Postfix(Code, 1), bR);

{построить новый узел}

b := ConsTBT (bL, bR)

end

end {F_Sh}
Стартовый вызов процедуры построения кода Фано-Шеннона происходит следующим образом:

Code := Create;

S := 0;

for i := 1 to n do S := S + w[i];

F_Sh (w, S, 1, n, Code, b)

В результате будет построено дерево b и заполнен массив кодовых слов CodeFS[1..n].

Рассмотрим теперь реализацию алгоритма Хаффмана. Для организации действий с узлами дерева и их весами будем использовать специальную структуру данных SW, в которой для каждого узла b хранится запись с двумя полями: b.tree – ссылка на узел и b.w – вес узла. Веса используются на этапе построения дерева, но в само дерево не включаются. Кодовое дерево представляется бинарным деревом с размеченными листьями. Для структуры данных SW, содержащей набор записей, определены следующие операции:

  1. функция Create, порождающая пустой набор данных, и функция Size(SW) – мощность набора;

  2. процедура MinElem(SW, b), выделяющая из набора SW узел b.tree с минимальным значением b.w и исключающая запись b из набора;

  3. процедура Insert(SW, b), добавляющая запись b в набор данных SW, так чтобы дальнейшее извлечение данных с помощью процедуры MinElem происходило корректно.

Тогда алгоритм Хаффмана может быть представлен в следующем итеративном виде:
SW := Create;

{инициализация SW листьями дерева}

for i := 1 to n do

begin

b.tree := MakeLeaf (i);

b.w := w[i];

Insert(SW, b)

end {for};

{построение дерева Хаффмана}

while Size(SW) > 1 do

begin

MinElem(SW, b1);

MinElem(SW, b2);

b.tree := ConsTBT(b1.tree, b2.tree);

b.w := b1.w + b2.w;

Insert(SW, b)

end {while};

{ Size(SW) = 1 и b.tree   корень дерева Хаффмана}
После завершения построения дерева Хаффмана кодирование можно осуществить, например, следующей рекурсивной процедурой:

procedure Coder (b: TBT; c: SeqB);

{Global: CodeH: array [Num] of SeqB}

begin

if IsLeaf (b) then CodeH[b.Info] := c

else

begin

Coder (LeftTBT (b), Postfix(c, 0));

Coder (RightTBT (b), Postfix(c, 1))

end

end {Coder}
со стартовым вызовом
c := Create;

Coder (b.tree, c)
В процедуре Coder использована функция (предикат) IsLeaf (b), определяющая является ли узел дерева листом: если b.Tag = Leaf, то «да».

Процедура декодирования полученного кода для восстановления входной последовательности (a1, a2, …, am) по кодовому дереву (Фано-Шеннона или Хаффмана) приведена далее. В ней использован глобальный массив Alpha[1..n] исходных кодов алфавита A = {1, 2, …, n}.
procedure DeCoder ({in:} c: SeqB; b: TBT; {out:} var AS: SeqA);

{ in: c  закодированное сообщение; b  кодовое дерево}

{ out: AS  декодированная последовательность символов алфавита}

var x: Bit;

begin

while not Null(c) do

begin {обработка (декодирование) кода}

p := b;

while not IsLeaf (p) do

begin

x := First (c); c := Rest (c);

if x=0 then p := Left (p) else p := Right (p)

end {while}

{ IsLeaf (p) }

AS := Postfix (AS, Alpha[p.Info])

end {while}

end {DeCder}
Стартовый вызов процедуры декодирования есть:

A := Create;

DeCoder (c, b, A);
Затем оценка количества операций и т.п.