ΠΠ»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌ Π·Π° компрСсия Π₯Π°Ρ„Ρ„ΠΌΠ°Π½

Π’ Π½Π°Π²Π΅Ρ‡Π΅Ρ€ΠΈΠ΅Ρ‚ΠΎ Π½Π° старта Π½Π° курса «Алгоритми Π·Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈΒ» ΠΏΠΎΠ΄Π³ΠΎΡ‚Π²ΠΈΡ…ΠΌΠ΅ Π·Π° вас ΠΏΡ€Π΅Π²ΠΎΠ΄ Π½Π° ΠΎΡ‰Π΅ Π΅Π΄ΠΈΠ½ ΠΏΠΎΠ»Π΅Π·Π΅Π½ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π».

ΠšΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π₯Π°Ρ„Ρ„ΠΌΠ°Π½ Π΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌ Π·Π° компрСсия Π½Π° Π΄Π°Π½Π½ΠΈ, ΠΊΠΎΠΉΡ‚ΠΎ Ρ„ΠΎΡ€ΠΌΡƒΠ»ΠΈΡ€Π° основната идСя Π½Π° компрСсията Π½Π° Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅. Π’ Ρ‚Π°Π·ΠΈ статия Ρ‰Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π·Π° ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ с фиксирана ΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° дълТина, ΡƒΠ½ΠΈΠΊΠ°Π»Π½ΠΎ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅ΠΌΠΈΡ‚Π΅ ΠΊΠΎΠ΄ΠΎΠ²Π΅, прСфикснитС ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΈ ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π΄ΡŠΡ€Π²ΠΎ Π₯Π°Ρ„Ρ„ΠΌΠ°Π½.

Π—Π½Π°Π΅ΠΌ, Ρ‡Π΅ всСки символ сС ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° ΠΊΠ°Ρ‚ΠΎ послСдоватСлност ΠΎΡ‚ 0 ΠΈ 1 ΠΈ Π·Π°Π΅ΠΌΠ° 8 Π±ΠΈΡ‚Π°. Π’ΠΎΠ²Π° сС Π½Π°Ρ€ΠΈΡ‡Π° ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ с фиксирана дълТина, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ всСки символ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π΅Π΄Π½Π°ΠΊΠ²ΠΎ фиксирано количСство Π±ΠΈΡ‚ΠΎΠ²Π΅ Π·Π° ΡΡŠΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅.

Π”Π° ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Π΅ ΠΈΠΌΠ°ΠΌΠ΅ тСкст. Как ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π½Π°ΠΌΠ°Π»ΠΈΠΌ количСството пространство, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π° ΡΡŠΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Π½Π° Π΅Π΄ΠΈΠ½ символ?

ΠžΡΠ½ΠΎΠ²Π½Π°Ρ‚Π° идСя Π΅ Π² ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ с ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° дълТина. МоТСм Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Ρ„Π°ΠΊΡ‚Π°, Ρ‡Π΅ някои символи Π² тСкста сС срСщат ΠΏΠΎ-чСсто ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈ (Π²ΠΆ. Ρ‚ΡƒΠΊ), Π·Π° Π΄Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌ, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ прСдставя ΡΡŠΡ‰Π°Ρ‚Π° послСдоватСлност ΠΎΡ‚ символи с ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΎ Π±ΠΈΡ‚ΠΎΠ²Π΅. ΠŸΡ€ΠΈ ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ с ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° дълТина присвоявамС Π½Π° символитС ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΎ количСство Π±ΠΈΡ‚ΠΎΠ²Π΅ Π² зависимост ΠΎΡ‚ чСстотата Π½Π° тяхното появяванС Π² дадСния тСкст. Π’ ΠΊΡ€Π°ΠΉΠ½Π° смСтка, някои символи ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π·Π°Π΅ΠΌΠ°Ρ‚ само 1 Π±ΠΈΡ‚, Π° Π΄Ρ€ΡƒΠ³ΠΈ 2, 3 ΠΈΠ»ΠΈ ΠΏΠΎΠ²Π΅Ρ‡Π΅. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡŠΡ‚ с ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ с ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° дълТина Π΅ СдинствСно Π² послСдващото Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅ Π½Π° послСдоватСлността.

Как, Π·Π½Π°Π΅ΠΉΠΊΠΈ послСдоватСлността ΠΎΡ‚ Π±ΠΈΡ‚ΠΎΠ²Π΅, Π΄Π° я Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€Π°ΠΌΠ΅ Π΅Π΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ?

НСка Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Ρ€Π΅Π΄ΠΈΡ†Π°Ρ‚Π° Β«aabacdabΒ». Π’ нСя ΠΈΠΌΠ° 8 символа ΠΈ ΠΏΡ€ΠΈ ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ с фиксирана дълТина Π·Π° ΡΡŠΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Ρ‰Π΅ са Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ 64 Π±ΠΈΡ‚Π°. Π—Π°Π±Π΅Π»Π΅ΠΆΠ΅Ρ‚Π΅, Ρ‡Π΅ чСстотата Π½Π° символитС Β«aΒ», Β«bΒ», Β«cΒ» ΠΈ Β«dΒ» Π΅ 4, 2, 1, 1 ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΎ. НСка ΠΎΠΏΠΈΡ‚Π°ΠΌΠ΅ Π΄Π° прСдставим Β«aabacdabΒ» с ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΎ Π±ΠΈΡ‚ΠΎΠ²Π΅, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ Ρ„Π°ΠΊΡ‚Π°, Ρ‡Π΅ Β«aΒ» сС срСща ΠΏΠΎ-чСсто ΠΎΡ‚ Β«bΒ», Π° Β«bΒ» сС срСща ΠΏΠΎ-чСсто ΠΎΡ‚ Β«cΒ» ΠΈ Β«dΒ». Π©Π΅ Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌ с ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° Β«aΒ» с Π΅Π΄ΠΈΠ½ Π±ΠΈΡ‚, Ρ€Π°Π²Π΅Π½ Π½Π° 0, Β«bΒ» Π½ΠΈΠ΅ Ρ‰Π΅ присвоим Π΄Π²ΡƒΠ±ΠΈΡ‚ΠΎΠ² ΠΊΠΎΠ΄ 11, Π° с Ρ‚Ρ€ΠΈ Π±ΠΈΡ‚Π° 100 ΠΈ 011 Ρ‰Π΅ ΠΊΠΎΠ΄ΠΈΡ€Π° Β«cΒ» ΠΈ Β«dΒ».

Π’ ΠΊΡ€Π°ΠΉΠ½Π° смСтка Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ:

a
0

b
11

с
100

d
011

Π’Π°ΠΊΠ° Ρ‰Π΅ ΠΊΠΎΠ΄ΠΈΡ€Π°ΠΌΠ΅ Ρ€Π΅Π΄ΠΈΡ†Π°Ρ‚Π° Β«aabacdabΒ» , ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΠΊΠΎΠ΄ΠΎΠ²Π΅Ρ‚Π΅, прСдставСни ΠΏΠΎ-Π³ΠΎΡ€Π΅. ΠžΡΠ½ΠΎΠ²Π½ΠΈΡΡ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ ΠΎΠ±Π°Ρ‡Π΅ Ρ‰Π΅ бъдС Π² Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ. ΠšΠΎΠ³Π°Ρ‚ΠΎ ΠΎΠΏΠΈΡ‚Π°ΠΌΠ΅ Π΄Π° Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€Π°ΠΌΠ΅ Ρ€Π΅Π΄ΠΈΡ†Π°Ρ‚Π° 00110100011011 (0|0|11|0|100|011|0|11), Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Π½Π΅Π΅Π΄Π½ΠΎΠ·Π½Π°Ρ‡Π΅Π½ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ тя ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС прСдставСна ΠΊΠ°Ρ‚ΠΎ: 001101000110110|011|0|100|011|0|11 adacdab 0|0|11|0|100|0|11|011 aabacabd 0|011|0|100|0|11|0|11 adacabab

0|011|0|100|011|0|11    adacdab
0|0|11|0|100|0|11|011   aabacabd
0|011|0|100|0|11|0|11   adacabab 

…
ΠΈ Ρ‚.Π½.

Π—Π° Π΄Π° ΠΈΠ·Π±Π΅Π³Π½Π΅ΠΌ Ρ‚Π°Π·ΠΈ нСяснота, трябва Π΄Π° Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π°ΠΌΠ΅, Ρ‡Π΅ Π½Π°ΡˆΠ΅Ρ‚ΠΎ ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅ отговаря Π½Π° понятиСто ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ Π·Π° прСфикс, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΡ‚ своя страна ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π²Π°, Ρ‡Π΅ ΠΊΠΎΠ΄ΠΎΠ²Π΅Ρ‚Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€Π°Π½ΠΈ само ΠΏΠΎ Π΅Π΄ΠΈΠ½ ΡƒΠ½ΠΈΠΊΠ°Π»Π΅Π½ Π½Π°Ρ‡ΠΈΠ½. ΠŸΡ€Π°Π²ΠΈΠ»ΠΎ Π·Π° прСфикс Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π°, Ρ‡Π΅ Π½ΠΈΠΊΠΎΠΉ ΠΊΠΎΠ΄ Π½Π΅ Π΅ прСфикс Π½Π° Π΄Ρ€ΡƒΠ³. Под ΠΊΠΎΠ΄ ΠΈΠΌΠ°ΠΌΠ΅ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ Π±ΠΈΡ‚ΠΎΠ²Π΅Ρ‚Π΅, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ΠΈ Π·Π° прСдставянС Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π΅Π½ символ. Π’ горния ΠΏΡ€ΠΈΠΌΠ΅Ρ€ 0 – Π΅ прСфикс 011, ΠΊΠΎΠ΅Ρ‚ΠΎ Π½Π°Ρ€ΡƒΡˆΠ°Π²Π° ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΡ‚ΠΎ Π·Π° прСфикс. И Ρ‚Π°ΠΊΠ°, Π°ΠΊΠΎ Π½Π°ΡˆΠΈΡ‚Π΅ ΠΊΠΎΠ΄ΠΎΠ²Π΅ отговарят Π½Π° ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΡ‚ΠΎ Π·Π° прСфикс, Ρ‚ΠΎ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠΈ Π΅Π΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ (ΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ).

НСка ΠΏΡ€Π΅Π³Π»Π΅Π΄Π°ΠΌΠ΅ горния ΠΏΡ€ΠΈΠΌΠ΅Ρ€. Π’ΠΎΠ·ΠΈ ΠΏΡŠΡ‚ Ρ‰Π΅ Π·Π°Π΄Π°Π΄Π΅ΠΌ Π½Π° символитС Β«aΒ», Β«bΒ», Β«cΒ» ΠΈ Β«dΒ» ΠΊΠΎΠ΄ΠΎΠ²Π΅, отговарящи Π½Π° ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΡ‚ΠΎ Π·Π° прСфикс.

a
0

b
10

с
110

d
111

Π‘ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Ρ‚Π°ΠΊΠΎΠ²Π° ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅, Π½ΠΈΠ·ΡŠΡ‚ Β«aabacdabΒ» Ρ‰Π΅ бъдС ΠΊΠΎΠ΄ΠΈΡ€Π°Π½ΠΎ ΠΊΠ°Ρ‚ΠΎ 00100100011010 (0|0|10|0|100|011|0|10). А Π΅Ρ‚ΠΎ, Ρ‡Π΅ 00100100011010 Π²Π΅Ρ‡Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€Π°ΠΌΠ΅ Π΅Π΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ ΠΈ Π΄Π° сС Π²ΡŠΡ€Π½Π΅ΠΌ към нашия ΠΈΠ·Ρ…ΠΎΠ΄Π΅Π½ Π½ΠΈΠ· Β«aabacdabΒ».

ΠšΠΎΠ΄ΠΈΡ€Π°Π½Π΅ Π½Π° Π₯Π°Ρ„Ρ„ΠΌΠ°Π½

Π‘Π΅Π³Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ смС Ρ€Π°Π·Π±Ρ€Π°Π»ΠΈ ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅ с ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° дълТина ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ Π·Π° прСфикс, Π½Π΅ΠΊΠ° ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π·Π° ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅ Π½Π° Π₯Π°Ρ„Ρ„ΠΌΠ°Π½.

ΠœΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ сС основава Π½Π° ΡΡŠΠ·Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π΄Π²ΠΎΠΈΡ‡Π½ΠΈ Π΄ΡŠΡ€Π²Π΅Ρ‚Π°. Π’ Π½Π΅Π³ΠΎ Π²ΡŠΠ·Π΅Π»ΡŠΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΈΠ»ΠΈ крайния, ΠΈΠ»ΠΈ Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ½ΠΈΡ. ΠŸΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ всички възли сС считат Π·Π° листа (ΠΊΡ€Π°ΠΉΠ½ΠΈ), ΠΊΠΎΠΈΡ‚ΠΎ прСдставляват самия символ ΠΈ Π½Π΅Π³ΠΎΠ²ΠΎΡ‚ΠΎ Ρ‚Π΅Π³Π»ΠΎ (Ρ‚.Π΅. чСстотата Π½Π° появата). Π’ΡŠΡ‚Ρ€Π΅ΡˆΠ½ΠΈΡ‚Π΅ възли ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‚ Ρ‚Π΅Π³Π»ΠΎ Π½Π° символа ΠΈ сС отнасят към Π΄Π²Π° наслСдника. По ΠΎΠ±Ρ‰ΠΎ съгласиС, Π±ΠΈΡ‚ΡŠΡ‚ "0" прСдставлява слСдванСто ΠΏΠΎ лявото ΠΊΠ»ΠΎΠ½Ρ‡Π΅, Π° "1" β€” ΠΏΠΎ дясното. Π’ пълно Π΄ΡŠΡ€Π²ΠΎ N листа ΠΈ N-1 Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ½ΠΈ възли. ΠŸΡ€Π΅ΠΏΠΎΡ€ΡŠΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Π΅ ΠΏΡ€ΠΈ строСнСто Π½Π° Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„Ρ„ΠΌΠ°Π½ Π΄Π° сС отстраняват Π½Π΅ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ΠΈΡ‚Π΅ символи, Π·Π° Π΄Π° сС ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ ΠΊΠΎΠ΄ΠΎΠ²Π΅ с ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π½Π° дълТина.

Π©Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ опашка с ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΈ Π·Π° построяванС Π½Π° Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„Ρ„ΠΌΠ°Π½, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ Π½Π° възСла с Π½Π°ΠΉ-ниска чСстота Ρ‰Π΅ бъдС ΠΏΡ€ΠΈΡΡŠΠ΄Π΅Π½ Π½Π°ΠΉ-висок ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚. По-Π΄ΠΎΠ»Ρƒ са описани ΡΡ‚ΡŠΠΏΠΊΠΈΡ‚Π΅ Π·Π° построяванС:

  1. Π‘ΡŠΠ·Π΄Π°ΠΉΡ‚Π΅ листов възСл Π·Π° всСки символ ΠΈ Π³ΠΈ Π΄ΠΎΠ±Π°Π²Π΅Ρ‚Π΅ Π² ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° с ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΈ.
  2. Π”ΠΎΠΊΠ°Ρ‚ΠΎ Π² ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° ΠΈΠΌΠ° ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ Π΅Π΄ΠΈΠ½ лист, ΠΏΡ€Π°Π²ΠΈΠΌ слСдното:
    • ΠŸΡ€Π΅ΠΌΠ°Ρ…Π½Π΅Ρ‚Π΅ Π΄Π²Π° възСла с Π½Π°ΠΉ-висок ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ (с Π½Π°ΠΉ-ниска чСстота) ΠΎΡ‚ ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π°;
    • Π‘ΡŠΠ·Π΄Π°ΠΉΡ‚Π΅ Π½ΠΎΠ² Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ΅Π½ възСл, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ Ρ‚Π΅Π·ΠΈ Π΄Π²Π° възСла Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ наслСдници, Π° чСстотата Π½Π° появата Ρ‰Π΅ бъдС Ρ€Π°Π²Π½Π° Π½Π° сумата Π½Π° чСстотитС Π½Π° Ρ‚Π΅Π·ΠΈ Π΄Π²Π° възСла.
    • Π”ΠΎΠ±Π°Π²Π΅Ρ‚Π΅ новия възСл Π² ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° с ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΈ.
  3. ΠŸΠΎΡΠ»Π΅Π΄Π½ΠΈΡΡ‚ оставащ възСл Ρ‰Π΅ бъдС ΠΊΠΎΡ€Π΅Π½ΠΎΠ², с Ρ‚ΠΎΠ²Π° ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡Π²Π°.

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π΅Ρ‚Π΅ си, Ρ‡Π΅ ΠΈΠΌΠ°ΠΌΠ΅ тСкст, ΠΊΠΎΠΉΡ‚ΠΎ сС ΡΡŠΡΡ‚ΠΎΠΈ само ΠΎΡ‚ символитС Β«aΒ», Β«bΒ», Β«cΒ», Β«dΒ» ΠΈ Β«eΒ», Π° чСстотитС Π½Π° тяхното появяванС са 15, 7, 6, 6 ΠΈ 5 ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΎ. По-Π΄ΠΎΠ»Ρƒ са ΠΈΠ»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ отразяват ΡΡ‚ΡŠΠΏΠΊΠΈΡ‚Π΅ Π½Π° Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌΠ°.

ΠΠ»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌ Π·Π° компрСсия Π₯Π°Ρ„Ρ„ΠΌΠ°Π½

ΠΠ»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌ Π·Π° компрСсия Π₯Π°Ρ„Ρ„ΠΌΠ°Π½

ΠΠ»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌ Π·Π° компрСсия Π₯Π°Ρ„Ρ„ΠΌΠ°Π½

ΠΠ»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌ Π·Π° компрСсия Π₯Π°Ρ„Ρ„ΠΌΠ°Π½

ΠΠ»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌ Π·Π° компрСсия Π₯Π°Ρ„Ρ„ΠΌΠ°Π½

ΠŸΡŠΡ‚ΡΡ‚ ΠΎΡ‚ ΠΊΠΎΡ€Π΅Π½Π° Π΄ΠΎ всСки крайния възСл Ρ‰Π΅ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π΅Π½ прСфиксСн ΠΊΠΎΠ΄ (извСстСн ΡΡŠΡ‰ΠΎ ΠΊΠ°Ρ‚ΠΎ ΠΊΠΎΠ΄ Π½Π° Π₯Π°Ρ„Ρ„ΠΌΠ°Π½), ΡΡŠΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π°Ρ‰ Π½Π° символа, ΡΠ²ΡŠΡ€Π·Π°Π½ с Ρ‚ΠΎΠ·ΠΈ крайния възСл.

ΠΠ»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌ Π·Π° компрСсия Π₯Π°Ρ„Ρ„ΠΌΠ°Π½
Π”ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„Ρ„ΠΌΠ°Π½

По-Π΄ΠΎΠ»Ρƒ Ρ‰Π΅ Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ рСализация Π½Π° Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌΠ° Π·Π° компрСсия Π½Π° Π₯Π°Ρ„Ρ„ΠΌΠ°Π½ Π½Π° Π΅Π·ΠΈΡ†ΠΈΡ‚Π΅ C++ ΠΈ Java:

#include <iostream>
#include <string>
#include <queue>
#include <unordered_map>
using namespace std;

// A Tree node
struct Node
{
	char ch;
	int freq;
	Node *left, *right;
};

// Function to allocate a new tree node
Node* getNode(char ch, int freq, Node* left, Node* right)
{
	Node* node = new Node();

	node->ch = ch;
	node->freq = freq;
	node->left = left;
	node->right = right;

	return node;
}

// Comparison object to be used to order the heap
struct comp
{
	bool operator()(Node* l, Node* r)
	{
		// highest priority item has lowest frequency
		return l->freq > r->freq;
	}
};

// traverse the Huffman Tree and store Huffman Codes
// in a map.
void encode(Node* root, string str,
			unordered_map<char, string> &huffmanCode)
{
	if (root == nullptr)
		return;

	// found a leaf node
	if (!root->left && !root->right) {
		huffmanCode[root->ch] = str;
	}

	encode(root->left, str + "0", huffmanCode);
	encode(root->right, str + "1", huffmanCode);
}

// traverse the Huffman Tree and decode the encoded string
void decode(Node* root, int &index, string str)
{
	if (root == nullptr) {
		return;
	}

	// found a leaf node
	if (!root->left && !root->right)
	{
		cout << root->ch;
		return;
	}

	index++;

	if (str[index] =='0')
		decode(root->left, index, str);
	else
		decode(root->right, index, str);
}

// Builds Huffman Tree and decode given input text
void buildHuffmanTree(string text)
{
	// count frequency of appearance of each character
	// and store it in a map
	unordered_map<char, int> freq;
	for (char ch: text) {
		freq[ch]++;
	}

	// Create a priority queue to store live nodes of
	// Huffman tree;
	priority_queue<Node*, vector<Node*>, comp> pq;

	// Create a leaf node for each characterΒ and add it
	// to the priority queue.
	for (auto pair: freq) {
		pq.push(getNode(pair.first, pair.second, nullptr, nullptr));
	}

	// do till there is more than one node in the queue
	while (pq.size() != 1)
	{
		// Remove the two nodes of highest priority
		// (lowest frequency) from the queue
		Node *left = pq.top(); pq.pop();
		Node *right = pq.top();	pq.pop();

		// Create a new internal node with these two nodes
		// as children and with frequency equal to the sum
		// of the two nodes' frequencies. Add the new node
		// to the priority queue.
		int sum = left->freq + right->freq;
		pq.push(getNode(' ', sum, left, right));
	}

	// root stores pointer to root of Huffman Tree
	Node* root = pq.top();

	// traverse the Huffman Tree and store Huffman Codes
	// in a map. Also prints them
	unordered_map<char, string> huffmanCode;
	encode(root, "", huffmanCode);

	cout << "Huffman Codes are :n" << 'n';
	for (auto pair: huffmanCode) {
		cout << pair.first << " " << pair.second << 'n';
	}

	cout << "nOriginal string was :n" << text << 'n';

	// print encoded string
	string str = "";
	for (char ch: text) {
		str += huffmanCode[ch];
	}

	cout << "nEncoded string is :n" << str << 'n';

	// traverse the Huffman Tree again and this time
	// decode the encoded string
	int index = -1;
	cout << "nDecoded string is: n";
	while (index < (int)str.size() - 2) {
		decode(root, index, str);
	}
}

// Huffman coding algorithm
int main()
{
	string text = "Huffman coding is a data compression algorithm.";

	buildHuffmanTree(text);

	return 0;
}

import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;

// Π’ΡŠΠ·Π΅Π» Π½Π° Π΄ΡŠΡ€Π²ΠΎ
class Node
{
	char ch;
	int freq;
	Node left = null, right = null;

	Node(char ch, int freq)
	{
		this.ch = ch;
		this.freq = freq;
	}

	public Node(char ch, int freq, Node left, Node right) {
		this.ch = ch;
		this.freq = freq;
		this.left = left;
		this.right = right;
	}
};

class Huffman
{
	// ΠΎΠ±Ρ…ΠΎΠΆΠ΄Π°Π½Π΅ Π½Π° Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½ ΠΈ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠΎΠ΄ΠΎΠ²Π΅Ρ‚Π΅ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½
	// Π² ΠΊΠ°Ρ€Ρ‚Π°.
	public static void encode(Node root, String str,
							  Map huffmanCode)
	{
		if (root == null)
			return;

		// Π½Π°ΠΌΠ΅Ρ€Π΅Π½ Π΅ листов възСл
		if (root.left == null && root.right == null) {
			huffmanCode.put(root.ch, str);
		}

		
		encode(root.left, str + "0", huffmanCode);
		encode(root.right, str + "1", huffmanCode);
	}

	// ΠΎΠ±Ρ…ΠΎΠΆΠ΄Π°Π½Π΅ Π½Π° Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½ ΠΈ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π°Ρ‚Π° Π½ΠΈΠ·
	public static int decode(Node root, int index, StringBuilder sb)
	{
		if (root == null)
			return index;

		// Π½Π°ΠΌΠ΅Ρ€Π΅Π½ Π΅ листов възСл
		if (root.left == null && root.right == null)
		{
			System.out.print(root.ch);
			return index;
		}

		index++;

		if (sb.charAt(index) == '0')
			index = decode(root.left, index, sb);
		else
			index = decode(root.right, index, sb);

		return index;
	}

	// Π˜Π·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅ Π½Π° Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½ ΠΈ ΠΊΠΎΠ΄ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½ ΠΈ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅ Π½Π° подадСния тСкст
	public static void buildHuffmanTree(String text)
	{
		// прСброяванС Π½Π° чСстотата Π½Π° поява Π½Π° всСки символ
		// ΠΈ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Π½Π΅Ρ‚ΠΎ ΠΌΡƒ Π² ΠΊΠ°Ρ€Ρ‚Π°
		Map freq = new HashMap();
		for (int i = 0 ; i < text.length(); i++) {
			if (!freq.containsKey(text.charAt(i))) {
				freq.put(text.charAt(i), 0);
			}
			freq.put(text.charAt(i), freq.get(text.charAt(i)) + 1);
		}

		// БъздаванС Π½Π° ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½Π° опашка Π·Π° ΡΡŠΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Π½Π° ΠΆΠΈΠ²ΠΈΡ‚Π΅ възли Π½Π° Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½
		// ΠžΠ±ΡŠΡ€Π½Π΅Ρ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Π΅ Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΡŠΡ‚ с Π½Π°ΠΉ-висок ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ ΠΈΠΌΠ° Π½Π°ΠΉ-ниска чСстота
		PriorityQueue pq = new PriorityQueue(
										(l, r) -> l.freq - r.freq);

		// БъздаванС Π½Π° листов възСл Π·Π° всСки символ ΠΈ добавянСто ΠΌΡƒ
		// Π² ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½Π°Ρ‚Π° опашка.
		for (Map.Entry entry : freq.entrySet()) {
			pq.add(new Node(entry.getKey(), entry.getValue()));
		}

		// ΠΏΡ€Π°Π²Π΅Ρ‚Π΅, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Π² ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° ΠΈΠΌΠ° ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ Π΅Π΄ΠΈΠ½ възСл
		while (pq.size() != 1)
		{
			// ΠŸΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½Π΅ Π½Π° Π΄Π²Π°Ρ‚Π° възСла с Π½Π°ΠΉ-висок ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚
			// (Π½Π°ΠΉ-ниска чСстота) ΠΎΡ‚ ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π°
			Node left = pq.poll();
			Node right = pq.poll();

			// БъздаванС Π½Π° Π½ΠΎΠ² Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ΅Π½ възСл с Ρ‚Π΅Π·ΠΈ Π΄Π²Π° възСла ΠΊΠ°Ρ‚ΠΎ Π΄Π΅Ρ†Π°
			// ΠΈ с чСстота, Ρ€Π°Π²Π½Π° Π½Π° сумата Π½Π° чСстотитС Π½Π° Π΄Π²Π°Ρ‚Π° възСла.
			// ДобавянС Π½Π° новия възСл Π² ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½Π°Ρ‚Π° опашка.
			int sum = left.freq + right.freq;
			pq.add(new Node(' ', sum, left, right));
		}

		// root ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π» към ΠΊΠΎΡ€Π΅Π½Π° Π½Π° Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½
		Node root = pq.peek();

		// ΠΎΠ±Ρ…ΠΎΠΆΠ΄Π°Π½Π΅ Π½Π° Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½ ΠΈ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠΎΠ΄ΠΎΠ²Π΅Ρ‚Π΅ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½ Π² ΠΊΠ°Ρ€Ρ‚Π°
		Map huffmanCode = new HashMap();
		encode(root, "", huffmanCode);

		// ΠΎΡ‚ΠΏΠ΅Ρ‡Π°Ρ‚Π²Π°Π½Π΅ Π½Π° ΠΊΠΎΠ΄ΠΎΠ²Π΅Ρ‚Π΅ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½
		System.out.println("ΠšΠΎΠ΄ΠΎΠ²Π΅Ρ‚Π΅ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½ са :\n");
		for (Map.Entry entry : huffmanCode.entrySet()) {
			System.out.println(entry.getKey() + " " + entry.getValue());
		}

		System.out.println("\nΠžΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½ΠΈΡΡ‚ Π½ΠΈΠ· бСшС :\n" + text);

		// ΠΎΡ‚ΠΏΠ΅Ρ‡Π°Ρ‚Π²Π°Π½Π΅ Π½Π° ΠΊΠΎΠ΄ΠΈΡ€Π°Π½ Π½ΠΈΠ·
		StringBuilder sb = new StringBuilder();
		for (int i = 0 ; i < text.length(); i++) {
			sb.append(huffmanCode.get(text.charAt(i)));
		}

		System.out.println("\nΠšΠΎΠ΄ΠΈΡ€Π°Π½ с Π½ΠΈΠ· Π΅ :\n" + sb);

		// ΠΎΡ‚Π½ΠΎΠ²ΠΎ ΠΎΠ±Ρ…ΠΎΠΆΠ΄Π°Π½Π΅ Π½Π° Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½ ΠΈ Ρ‚ΠΎΠ·ΠΈ ΠΏΡŠΡ‚
		// Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π°Ρ‚Π° Π½ΠΈΠ·
		int index = -1;
		System.out.println("\nДСкодираният Π½ΠΈΠ· Π΅: \n");
		while (index < sb.length() - 2) {
			index = decode(root, index, sb);
		}
	}

	public static void main(String[] args)
	{
		String text = "ΠšΠΎΠ΄ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π₯Π°Ρ„ΠΌΠ°Π½ Π΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌ Π·Π° компрСсия Π½Π° Π΄Π°Π½Π½ΠΈ.";

		buildHuffmanTree(text);
	}
}

Π‘Π΅Π»Π΅ΠΆΠΊΠ°: ΠŸΠ°ΠΌΠ΅Ρ‚Ρ‚Π°, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π° ΠΎΡ‚ Π²Ρ…ΠΎΠ΄Π½Π°Ρ‚Π° линия, Π΅ 47 * 8 = 376 Π±ΠΈΡ‚, Π° ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π°Ρ‚Π° линия Π·Π°Π΅ΠΌΠ° само 194 Π±ΠΈΡ‚Π°, Ρ‚.Π΅. Π΄Π°Π½Π½ΠΈΡ‚Π΅ сС компрСсират с ΠΎΠΊΠΎΠ»ΠΎ 48%. Π’ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π½Π° C++ ΠΏΠΎ-Π³ΠΎΡ€Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ класа string Π·Π° ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠΎΠ΄ΠΈΡ€Π°Π½Π°Ρ‚Π° линия, Π·Π° Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Ρ‡Π΅Ρ‚ΠΈΠΌΠ°.

Въй ΠΊΠ°Ρ‚ΠΎ Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΈΡ‚Π΅ структури ΠΎΡ‚ Π΄Π°Π½Π½ΠΈ Π·Π° ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½ΠΈ опашки изискват O(log(N)) Π²Ρ€Π΅ΠΌΠ΅ Π·Π° вмъкванС, Π° Π² пълно Π΄Π²ΠΎΠΈΡ‡Π½ΠΎ Π΄ΡŠΡ€Π²ΠΎ с N листата ΠΈΠΌΠ° 2N-1 възли, ΠΈ Π΄ΡŠΡ€Π²ΠΎΡ‚ΠΎ Π½Π° Π₯Π°Ρ„Ρ„ΠΌΠ°Π½ Π΅ пълно Π΄Π²ΠΎΠΈΡ‡Π½ΠΎ Π΄ΡŠΡ€Π²ΠΎ, слСдоватСлно Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΡŠΠΌΡŠΡ‚ Ρ€Π°Π±ΠΎΡ‚ΠΈ Π·Π° O(Nlog(N)) Π²Ρ€Π΅ΠΌΠ΅, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ N Π΅ броят Π½Π° символитС.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΡ†ΠΈ:

en.wikipedia.org/wiki/Huffman_coding
en.wikipedia.org/wiki/Variable-length_code
www.youtube.com/watch?v=5wRPin4oxCo

НаучСтС ΠΏΠΎΠ²Π΅Ρ‡Π΅ Π·Π° курса.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster