Tải bản đầy đủ (.doc) (32 trang)

Đề tài phương pháp mã Hóa Huffman Môn Lý Thuyết Đồ Thị

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.53 MB, 32 trang )

TRƯỜNG ĐH SƯ PHẠM TP. HỒ CHÍ MINH
KHOA TOÁN – TIN
------------------òòòòòò--------------------

MÔN LÝ THUYẾT ĐỒ THỊ
BÁO CÁO ĐỀ TÀI


LỜI NÓI ĐẦU
Trong thời buổi công nghệ thông tin bùng nổ hiện nay, cùng với sự phát triển hết sức mạnh mẽ
của nghành Tin Học. Khoa học máy tính đang dần chiếm lĩnh thế giới, chính vì vậy các môn học
về công nghệ máy vi tính luôn dẫn đầu hiện nay và Lý Thuyết Đồ Thị không ngoại lệ.
Năm 1736 với bài toán kinh điển “ 7 cây cầu ở Konigsburg” của nhà toán học Leonhard Euler
( 1707 – 1783 ) được công bố, mở rộng thêm hướng đi mới cho Tin học hiện đại.
Lý Thuyết Đồ Thị là môn học thú vị, giúp sinh viên có cơ hội làm quen với những bài toán cùng
nhiều thuật toán đồ thị ứng dụng cao trong thực tế…, qua đó nâng cao khả năng lập trình cho
sinh viên. Trong đó phương pháp mã hóa Huffman là một ví dụ, đây là một trong những
phương pháp nén hay đã có nhiều công trình nghiên cứu ứng dụng của nó vào thực tiễn. Vì vậ ,
em chọn đề tài để báo cáo.
Trong quá trình làm đề tài, em đã cố gắng học tập, tìm tài liệu, lắng nghe sự chỉ bảo tận tình của
thầy trong các buổi học. Do sự hiểu biết kiến thức chưa sâu về bộ môn lẫn kỹ thuật lập trình. Đề
tài hoàn thành nhưng vẫn còn nhiều thiết sót.
Xin thầy xem xét lượng thứ, và đóng góp ý kiến để em ý thức hơn và rút kinh nghiệm cho các
đề tài sau này.
Cuối cùng, em chân thành cám ơn thầy đã tạo cơ hội cho em hiện đề tài.

NHẬN XÉT CỦA GIÁO VIÊN BỘ MÔN

2



.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................

.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................
.............................................................................................................................................................................

MỤC LỤC

3


Chương 1 : TỔNG QUAN VỀ NÉN DỮ LIỆU
I.

II.
III.
IV.

Giới thiệu ..................................................................................................................5
Tỷ lệ nén ...................................................................................................................5
Phân loại các phương pháp nén ................................................................................5
Các phương pháp nén thứ nhất .................................................................................6
1. Mã hóa loạt dài RLC (Run Length Coding)
2. Mã hóa Huffman

3. Mã hóa LZW (Lempel Ziv-Wench)
V. Kết luận .....................................................................................................................8

Chương 2 : PHƯƠNG PHÁP MÃ HÓA HUFFMAN
PHẦN 1 : SƠ LƯỢC VỀ LỊCH SỬ PHƯƠNG PHÁP MÃ HUFFMAN...............................9
PHẦN 2 : MÃ TIỀN TỐ ( PREFIX-FREE BINARY CODE )
I. Nội dung ....................................................................................................................9
II. Biểu diễn mã tiền tố trên cây nhị phân .....................................................................10
III. Tính tối ưu của độ dài mã ........................................................................................13
PHẦN 3 : MÃ HUFFMAN
I. Nguyên tắc ................................................................................................................15
II. Định lý Huffman .......................................................................................................15
III. Phương pháp sinh mã Huffman ................................................................................15
IV. Cây Huffman .............................................................................................................17
V. Thuật toán .................................................................................................................20
VI. Tóm tắt các bước mã hóa và giải mã văn bản ...........................................................21

Chương 3 : VIẾT CHƯƠNG TRÌNH NÉN VÀ GIẢ NÉN
PHẦN 1 : HỖ TRỢ THỰC HIỆN ........................................................................................22

PHẦN 2 : TẠO MÃ HUFFMAN CHO MỘT XÂU KÝ TỰ
I. Tìm hiểu đoạn code ...................................................................................................22
II. Code chương trình ....................................................................................................24
III. Demo chương trình ...................................................................................................27
PHẦN 3 : CÀI ĐẶT CHƯƠNG TRÌNH NÉN VÀ GIẢI NÉN BẰNG C#
I. Hình ảnh phần mềm ..................................................................................................27
II. Code chương trình ....................................................................................................27
III. Demo chương trình ...................................................................................................28

CHƯƠNG 1 : TỔNG QUAN VỀ NÉN DỮ LIỆU

4


I. Giới thiệu
-

Trong các lĩnh vực của công nghệ thông tin – viễn thông hiện nay, thông tin được truyền tải
đi thường rất lớn, gây tốn kém tài nguyên mạng, tiêu phí khả năng của hệ thống… Để giải
quyết vấn đề đó, các thuật toán nén đã được ra đời.

-

Kỹ thuật nén tập tin thường được áp dụng cho :
 Các tập tin văn bản, trong đó có một số kí tự nào đó có xác suất xuất hiện nhiều hơn
các kí tự khác.
 Các tập tin ảnh bitmap mà có thể có những mảng lớn đồng nhất,
 Các tập tin dùng để biểu diễn âm thanh dưới dạng số hoá và các tín hiệu tương tự
(analog signal) khác các tín hiệu này có thể có các mẫu được lặp lại nhiều lần.


II. Tỷ lệ nén (Compression Rate)
Tỷ lệ nén là một trong các đặc trưng quan trọng nhất của mọi phương
pháp nén. Tuy
nhiên, về cách đánh giá và các kết quả công bố trong các tài liệu cũng cần
quan tâm xem xét.
Nhìn chung, người ta định nghĩa tỷ lệ cơ bản của phương pháp nén. Nhiều khi tỷ
lệ nén cao cũng
chưa thể nói phương pháp đó hiệu quả hơn các phương pháp khác, vì còn các
chi phí như thời
gian, không gian và thậm chí cả độ phức tạp tính toán nữa. Thí dụ như nén
phục vụ trong truyền
dữ liệu: vấn đề đặt ra là hiệu quả nén có tương hợp với đường truyền không.
Cũng cần phân biệt dữ liệu với nén băng truyền. Mục đích chính của nén
là giảm lượng
thông tin dư thừa và dẫn tới giảm kích thước dữ liệu. Tuy vậy, đôi khi quá
trình nén cũng làm
giảm băng truyền tín hiệu số hóa thấp hơn so với truyền tín hiệu tương tự.

III. Phân loại các phương pháp nén
Có nhiều cách phân loại các phương pháp nén khác nhau.
1.

Cách thứ nhất : Dựa vào nguyên lý nén. Cách này phân các phương pháp nén
thành hai họ:


Nén chính xác hay nén không mất thông tin: họ này bao gồm các
phương pháp nén mà
sau khi giải nén ta thu được chính xác dữ liệu gốc.




Nén có mất thông tin: họ này bao gồm các phương pháp mà sau khi
giải nén ta không
thu được dữ liệu như bản gốc. Phương pháp này lợi dụng tính chất của mắt
người, chấp nhận một
số vặn xoắn trong ảnh khi khôi phục lại. Tất nhiên, các phương pháp này chỉ
có hiệu quả khi mà

5


độ vặn xoắn chấp nhận được bằng mắt thường hay với dung sai nào đấy.
2.

Cách thứ hai : Dựa vào cách thức thực hiện nén. Theo cách này, người ta
cũng phân thành hai họ:


Phương pháp không gian (Spatial Data Compression): Các phương
pháp thuộc họ này
thực hiện nén bằng các tác động trực tiếp lên việc lấy mẫu của ảnh trong
miền không gian.


Phương pháp sử dụng biến đổi (Transform Coding): gồm các phương
pháp tác động lên
sự biến đổi của ảnh gốc mà không tác động trực tiếp như họ trên.

3.


Cách thứ ba : Dựa vào triết lý của sự mã hóa.Cách này phân các phương
pháp nén thành hai họ:


Các phương pháp nén thế hệ thứ nhất: Gồm các phương pháp mà
mức độ tính toán là đơn giản, thí dụ việc lấy mẫu, gán từ mã,.v.v.



Các phương pháp nén thế hệ thứ hai: dựa vào độ bão hòa của tỷ lệ
nén.

IV. Các phương pháp nén thứ nhất
-

Mã hóa loạt dài RLC (Run Length Coding)

-

Mã hóa Hufman

-

Mã hóa LZW (Lempel Ziv-Wench)

1. Phương pháp mã hoá độ dài loạt (Run-Length Encoding)
-

Ứng dụng trong : tập tin đồ họa bit map, vì ở đó thường có các mảng lớn cùng màu

được biểu diễn dưới dạng bitmap là các chuỗi bit có đường chạy dài. Trên thực tế, nó
được dùng trong các tập tin .PCX, .RLE, các vùng dữ liệu hằng của các tập tin chương
trình, một số tập tin văn bản...

-

Xét chuỗi : AAAABBB AA BBBBB CCCCCCCC DABCBAAABBBBCCCD
Chuỗi kí tự trên được mã hoá lại : 4A3BAA5B 8CDABCB3A4B3CD
Chú ý : là không đáng để mã hoá các loạt chạy có độ dài 1 hoặc 2 vì cần đến hai kí tự
để mã hoá.

-

Phương pháp nén tập tin kí tự đã được đề nghị ở trên sẽ không dùng được đối với các
chuỗi kí tự có chứa số. Nếu những kí tự khác được sử dụng để mã hoá các số đếm, thì
nó sẽ không làm việc với các chuỗi chứa các kí tự đó. Giả sử ta phải mã hoá bất kì kí tự
nào từ một bảng chữ cái cố định bằng cách chỉ dùng các kí tự từ bảng chữ cái đó. Ðể
minh hoạ, giả sử ta phải mã hoá bất kì một chuỗi nào từ một chữ cái đó, ta sẽ giả định
rằng ta chỉ có 26 chữ cái trong bảng chữ cái (và cả khoảng trống) để làm việc.

-

Ðể có thể dùng vài chữ cái để biểu diễn các số và các kí tự khác biểu diễn các phần tử
của chuỗi sẽ được mã hoá, ta phải chọn một kí tự được gọi là kí tự "Escape". Mỗi một
sự xuất hiện của kí tự đó báo hiệu rằng hai chữ cái tiếp theo sẽ tạo thành một cặp (số
6


đếm, kí tự) với các số đếm được biểu diễn bằng cách dùng kí tự thứ i của bảng chữ cái
để biểu diễn số i. Vì vậy, chuỗi ví dụ của chúng ta sẽ được biểu diễn như sau với Q

được xem là các kí tự "Escape"
QDA BBB AA BQH CDABCB AAA QDB CCC D
-

Tổ hợp của kí tự "Escape", số đếm và một kí tự lặp lại được gọi là một dãy Escape. Chú
ý rằng không đáng để mã hoá các đường chạy có chiều dài ít hơn bốn kí tự, vì ít nhất là
cần đến ba kí tự để mã hoá bất kì một loạt chạy nào.

-

Trong trường hợp bản thân kí tự "Escape" xuất hiện trong dãy kí tự cần mã hoá ta sử
dụng một dãy "Escape" với số đếm là 0 (kí tự space) để biểu diễn kí tự "Escape". Như
vậy trong trường hợp kí tự "Escape" xuất hiện nhiều thì có thể làm cho tập tin nén
phình to hơn trước.

-

Các loạt chạy dài có thể được cắt ra để mã hoá bằng nhiều dãy Escape, ví dụ, một loạt
chạy gồm 51 chữ A sẽ được mã hoá như QZAQYA bằng cách dùng trên.

2. Phương pháp nén Huffman
Dựa vào mô hình thống kê, tính tần suất xuất hiện của các ký tự, rồi gán cho các ký tự có tần suất
cao một từ mã ngắn, các ký tự tần suất thấp từ mã dài. Phương pháp này phải lưu giữ lại bảng mã
gắn kèm cùng với dữ liệu nén.

3. Phương pháp nén LZW
Thuật
toán
này


sự
chuyển
giao
của
thuật
toán
LZ78.
Phương pháp nén LZW được phát minh bởi Lempel - Zip và Welch. Nó hoạt động đựa trên một
ý tưởng rất đơn giản là người mã hoá và người giải mã cùng xây dựng bản mã.
Nguyên tắc hoạt động :
 Một xâu kí tự là một tập hợp từ hai kí tự trở lên.
 Nhớ tất cả các xâu kí tự đã gặp và gán cho nó một dấu hiệu (token) riêng.
 Nếu lần sau gặp lại xâu kí tự đó, xâu kí tự sẽ được thay thế bằng dấu hiệu của nó.
Phần quan trọng nhất của phương pháp nén này là phải tạo một mảng rất lớn dùng để lưu giữ các
xâu kí tự đã gặp (Mảng này được gọi là "Từ điển"). Khi các byte dữ liệu cần nén được đem đến,
chúng liền được giữ lại trong một bộ đệm chứa (Accumulator) và đem so sánh với các chuỗi đã
có trong "từ điển".
Nếu chuỗi dữ liệu trong bộ đệm chứa không có trong "từ điển" thì nó được bổ sung thêm vào "từ
điển" và chỉ số của chuỗi ở trong "từ điển" chính là dấu hiệu của chuỗi. Nếu chuỗi trong bộ đệm
chứa đã có trong "từ điển" thì dấu hiệu của chuỗi được đem ra thay cho chuỗi ở dòng dữ liệu ra.

7


Có bốn qui tắc để thực hiên việc nén dữ liệu theo thuật toán LZW là:
-

Qui tắc 1: 256 dấu hiệu đầu tiên được dành cho các kí tự đơn (0 - 0ffh).
Qui tắc 2: Cố gắng so sánh với "từ điển" khi trong bộ đệm chứa đã có nhiều hơn hai kí tự.
Qui tắc 3: Các kí tự ở đầu vào (Nhận từ tập tin sẽ được nén) được bổ sung vào bộ đệm

chứa đến khi chuỗi kí tự trong bộ đệm chứa không có trong "từ điển".
Qui tắc 4: Khi bộ đệm chứa có một chuỗi mà trong "từ điển" không có thì chuỗi trong bộ
đệm chứa được đem vào "từ điển". Kí tự cuối cùng của chuỗi kí tự trong bộ đệm chứa phải
ở lại trong bộ đệm chứa để tiếp tục tạo thành chuỗi mới.

III. Kết luận
Qua ba phương pháp nén được dùng phổ biến trên, ta thấy rằng, thuật toán nén độ dài loạt
(Runlength) không thể áp dụng cho nhiều loại tập tin được, ví dụ như tập tin chương trình, tập tin
cơ sở dữ liệu... vì ở đó các loạt chạy là rất ngắn, do đó nếu áp dụng thuật toán này không những
không làm bé tập tin mà còn làm phình to chúng.
Thuật toán nén LZW có các ưu điểm là hệ số nén tương đối cao, trong tập tin nén không cần phải
chứa bảng mã. Nhược điểm của thuật toán này là tốn nhiều bộ nhớ, khó thực hiện dựa trên các
mảng đơn giản (bé hơn 64KB).
Thuật toán còn lại Huffman đều có thể áp dụng được để nén nhiều loại tập tin trên các máy vi
tính.
8


Thuật toán Huffman có ưu điểm là hệ số nén tương đối cao, phương pháp thực hiện tương đối
đơn giản, đòi hỏi ít bộ nhớ, có thể xây dựng dựa trên các mảng bé hơn 64KB. Nhược điểm của
nó là phải chứa cả bảng mã vào tập tin nén thì phía nhận mới có thể giải mã được do đó hiệu suất
nén chỉ cao khi ta thực hiện nén các tập tin lớn.
Từ các ưu và nhược điểm trên, ta chọn phương pháp nén Huffman vì tính đơn giản của nó hệ số
nén lại cao.

CHƯƠNG 2: PHƯƠNG PHÁP MÃ HÓA HUFFMAN
PHẦN 1 : SƠ LƯỢC VỀ LỊCH SỬ PHƯƠNG PHÁP MÃ HUFFMAN
-

Thuật toán được đề xuất bởi David A. Huffman khi ông còn là sinh viên Ph.D. tại MIT,

và công bố năm 1952 trong bài báo "A Method for the Construction of MinimumRedundancy Codes". Sau này Huffman đã trở thành một giảng viên ở MIT và sau đó ở
khoa Khoa học máy tính của Đại học California, Santa Cruz, Trường Kỹ nghệ Baskin
(Baskin School of Engineering)

-

Trong khoa học máy tính và lý thuyết thông tin, mã Huffman là một thuật toán mã hóa
dùng để nén dữ liệu. Nó dựa trên bảng tần suất xuất hiện các kí tự cần mã hóa để xây
dựng một bộ mã nhị phân cho các kí tự đó sao cho dung lượng (số bít) sau khi mã hóa là
nhỏ nhất.

PHẦN 2 : MÃ TIỀN TỐ ( PREFIX-FREE BINARY CODE )
I. Nội dung :
Để mã hóa các kí hiệu (kí tự, chữ số, ...) ta thay chúng bằng các xâu nhị phân, được gọi là từ mã
của kí hiệu đó. Chẳng hạn bộ mã ASCII, mã hóa cho 256 kí hiệu là biểu diễn nhị phân của các số
từ 0 đến 255, mỗi từ mã gồm 8 bít.
Trong ASCII từ mã của kí tự "a" là 1100001, của kí tự "A" là 1000001. Trong cách mã hóa này
các từ mã của tất cả 256 kí hiệu có độ dài bằng nhau (mỗi từ mã 8 bít). Nó được gọi là mã hóa
với độ dài không đổi.
Khi mã hóa một tài liệu có thể không sử dụng đến tất cả 256 kí hiệu. Hơn nữa trong tài liệu chữ
cái "a" chỉ có thể xuất hiện 1000000 lần còn chữ cái "A" có thể chỉ xuất hiện 2, 3 lần. Như vậy ta
có thể không cần dùng đủ 8 bít để mã hóa cho một ký hiệu, hơn nữa độ dài (số bít) dành cho mỗi
kí hiệu có thể khác nhau, kí hiệu nào xuất hiện nhiều lần thì nên dùng số bít ít, ký hiệu nào xuất
hiện ít thì có thể mã hóa bằng từ mã dài hơn.
Như vậy ta có việc mã hóa với độ dài thay đổi. Tuy nhiên, nếu mã hóa với độ dài thay đổi, khi
giải mã ta làm thế nào phân biệt được xâu bít nào là mã hóa của ký hiệu nào. Một trong các giải
pháp là dùng các dấu phẩy (",") hoặc một kí hiệu quy ước nào đó để tách từ mã của các kí tự
9



đứng cạnh nhau. Nhưng như thế số các dấu phẩy sẽ chiếm một không gian đáng kể trong bản mã.
Một cách giải quyết khác dẫn đến khái niệm mã tiền tố


Mã tiền tố là bộ các từ mã của một tập hợp các kí hiệu sao cho từ mã của mỗi ký hiệu
không là tiền tố (phần đầu) của từ mã một ký hiệu khác trong bộ mã ấy.

Đương nhiên mã hóa với độ dài không đổi là mã tiền tố.







Ví dụ: Giả sử mã hóa từ "ARRAY", tập các ký hiệu cần mã hóa gồm 3 chữ cái
"A","R","Y".
Nếu mã hóa bằng các từ mã có độ dài bằng nhau ta dùng ít nhất 2 bit cho một chữ cái
chẳng hạn "A"=00, "R"=01, "Y"=10. Khi đó mã hóa của cả từ là 0001010010. Để giải
mã ta đọc hai bit một và đối chiếu với bảng mã.
Nếu mã hóa "A"=0, "R"=01, "Y"=11 thì bộ từ mã này không là mã tiền tố vì từ mã của
"A" là tiền tố của từ mã của "R". Để mã hóa cả từ ARRAY phải đặt dấu ngăn cách vào
giữa các từ mã 0,01,01,0,11
Nếu mã hóa "A"=0, "R"=10, "Y"=11 thì bộ mã này là mã tiền tố. Với bộ mã tiền tố này
khi mã hóa xâu "ARRAY" ta có 01010011.

II. Biểu diễn mã tiền tố trên cây nhị phân :




Nếu có một cây nhị phân n lá ta có thể tạo một bộ mã tiền tố cho n ký hiệu bằng cách đặt
mỗi ký hiệu vào một lá. Từ mã của mỗi kí hiệu được được tạo ra khi đi từ gốc tới lá chứa
ký hiệu đó, nếu đi qua cạnh trái thì ta thêm số 0, đi qua cạnh phải thì thêm số 1.
VÍ DỤ 1 : Cây 3 lá sau đây biểu diễn bộ mã của A ,R ,Y trong ví dụ trên



Từ mã của "A" là 0, của "R" là 10, của "Y" là 11.
VÍ DỤ 2 : Xét cây nhị phân trong hình sau



Khi đó ta có bảng mã :

10


Từ đó xâu 11111011100 là mã của từ same.
Ngược lại để kiểm tra xem một cách mã có phải là mã tiền tố hay không, cần phải biểu diễn
các mã đó thành cây nhị phân . Nếu các lá có nhãn là các chữ cái có trong bảng mã thì đó là
mã tiền tố, còn nếu tồn tại đỉnh trong có nhãn là chữ cái thì đó không phải là mã tiền tố.

Biểu diễn các mã thành cây nhị phân , ta có kết luận:

VÍ DỤ 3:
11


Giả sử có một bản tin gồm một dãy ký hiệu lấy trong một tập hữu hạn X. Biết rằng mỗi ký hiệu
trong X xuất hiện trong bản tin theo một xác suất cho trước. Ta muốn mã các ký hiệu này thành

những chuỗi bit nhị phân sao cho chiều dài chuỗi mã của bản tin là ngắn nhất.
Xét một bản tin gồm 1000 ký tự lấy trong tập các chữ cái A = { a,b,c,d,e} với tần suất sau :

Các cây mã tiền tố

Bộ mã 3 : Dựa trên nguyên lý đỉnh lá nào có tần suất càng lớn thì đường đi từ gốc cây tới đỉnh lá
đó càng ngắn.

12


Câu hỏi : Đặt ra bộ mã 3 là bộ tối ưu nhất ? Tại sao ?

III. Tính tối ưu của độ dài mã :
1. Định lý Shannon (1948)

2. Bảng mã tối ưu tuyệt đối :

13


3. Bảng mã tối ưu tương đối

4. Điều kiện nhận biết một bảng mã tối ưu

14


PHẦN 3 : MÃ HUFFMAN
I. Nguyên tắc

Phương pháp mã hóa Huffman là phương pháp dựa vào mô hình thống kê. Dựa vào dữ liệu gốc,
người ta tính tần suất xuất hiện của các ký tự. Việc tính tần suất được thực hiện bởi cách duyệt
tuần tự tệp gốc từ đầu đến cuối. Việc xử lý ở đây tính theo bit.
Trong phương pháp này người ta gán cho các ký tự có tần suất cao một từ mã ngắn, các ký tự có
tần suất thấp từ mã dài. Nói một cách khác, các ký tự có tần suất càng cao được gắn mã càng
ngắn và ngược lại. Rõ ràng với cách thức này, người ta đã làm giảm chiều dài trung bình của từ
mã hóa bằng cách dùng chiều dài biến đổi.

II. Định lý Huffman

15


III. Phương pháp sinh mã Huffman

16


IV. Cây Huffman

17


1. Định lý : Cây Huffman là cây mã tối ưu
Để chứng minh định lý ta xét bổ đề sau :

18


2. Thiết lập cây mã Huffman :

2.1 Mã Huffman :
Một mã phi tiền tố được biểu diễn bằng một cây nhị phân
 Các nút lá biểu diễn các ký tự và tần số xuất hiện của ký tự trong văn bản.
 Các nút trong hai nhánh tương tứng với : 0 – nhánh bên trái , 1 – nhánh bên phải.
Các nút này chứa tổng tần suất xuất hiện của các nút trong các nhánh con của nó.
 Một đường đi từ nút gốc đến nút lá là một mã nhị phân biểu diễn ký tự ở nút lá.
 Ký tự có tần suất lớn sẽ xuất hiện ở mức thấp hơn, ký tự có tần suất nhỏ sẽ xuất
hiện ở mức cao hơn trong cây Huffman.
2.2 Thiết lập
 Đầu vào : Bảng chữ cái C. Tần suất xuất hiện của các ký tự trong C
 Đầu ra : Cây mã hóa Huffman
 Ý tưởng :
- Dựng cây từ dưới lên, xuất phát với các nút lá.
- Tạo lập một nút nhánh ( nút trong ) bằng cách nhóm hai nhánh đã có sẵn
mà tần suất của hai nhánh đó là nhỏ nhất.

19


VÍ DỤ :

20


V. Thuật toán

21


VI. Tóm tắt các bước mã hóa và giải mã văn bản

1. Mã hóa văn bản sử dụng mã Huffman
1.
2.
3.
4.
5.

Duyệt văn bản cần mã hóa và xáx định tần suất xuất hiện của các ký tự .
Sắp xếp các ký tự dựa trên tần suất xuất hiện của chúng trong văn bản.
Xây dựng cây mã Huffman dựa trên dãy đã được sắp.
Duyệt cây để xác định mã của các ký tự.
Duyệt văn bản cần mã hóa và sinh văn bản mã hóa sử dụng mã có được trong bước 4.

2. Giải mã :
1. Xuất phát từ gốc của cây mã hóa.
2. Đọc lần lượt từng ký tự trong xâu mã hóa
 Nếu là 0 : đi sang trái.
 Nếu là 1 : đi sang phải.
3. Nếu chạm tới nút lá ghi ký tự chứa tại nút lá, sau đó quay lại nút gốc của cây mã hóa.

22


CHƯƠNG 3 : VIẾT CHƯƠNG TRÌNH NÉN VÀ GIẢI NÉN
PHẦN 1 : HỖ TRỢ THỰC HIỆN
I. Tài liệu tham khảo
1. Đoạn code tham khảo
-

Đọan code viết bằng C++ chạy trên DOS.

Đọan code viết bằng C# có giao diện.

2. Sách tham khảo
-

Lý thuyết đồ thị. PTS.Nguyễn Cam.
Toán rời rạc.
Vũ Kim Thành.
Xử lý ảnh.
Học viện BCVT
Cấu trúc dữ liệu nâng cao.
Phân tích thiết kế thuật giải.
Lập trình bằng C#
www.google.com.vn từ khóa “ Huffma, nén và giải nén, thuật giải… ”

II. Môi trường cài đặt
-

Viết bằng ngôn ngữ Visual C++ trên Dos.
Viết bằng ngôn ngữ C# Winform.

PHẦN 2 : TẠO MÃ HUFFMAN CHO MỘT XÂU KÝ TỰ
I. Tìm hiểu đoạn code
Mã số Huffman có hai tính chất sau :
 Mã của mỗi ký tự không được là phần đầu của mã của bất kỳ ký tự nào khác.
 Ký tự xuất hiệt càng nhiều thì mã phải càng ngắn.
Dựa vào tần số xuất hiện từng ký tự có thể tạo thành một cây nhị phân, các lá của cây là các ký
tự, ký tự có tần số càng bé càng ở tầng sâu hơn, mã của ký tự là đường đi từ gốc đến ký tự đó.
Thực chất là xây dựng cây từ các lá.
Thay cho cây ta sẽ trình bày thuật toán dưới dạng phân nhóm, có thể là dễ hiểu hơn và dễ cài đặt

hơn, mỗi cây con xem như một nhóm gồm các lá ( ký tự) của cây con đó.
Dùng mảng
Mảng
Mảng
Mảng

kt[i]
tanso[i]
ma[i]
tren[i] = k

: để lưu các ký tự của xâu.
: lưu tần số.
: để lưu mã số của ký tự thứ i.
: có nghĩa là ký tự I đang thuộc nhóm k.

Khởi đầu mã số các ký tự đều là xâu rỗng.

23


Trước hết phải tìm tần số xuất hiện của từng ký tự. Lần lượt đọc từng ký tự của xâu, nếu gặp ký
tự đã có trong mảng kt thì tăng tần số của ký tự đó, nếu là ký tự mới thì đưa thêm ký tự đó vào
mảng kt và gán tần số bằng 1.
Ta sẽ gộp dần các ký tự từ các nhóm nhỏ thành các nhóm lớn hơn cho đến khi chỉ còn một nhóm,
mỗi lần gộp nhóm lại bổ sung bên trái cho mã của từng ký tự. Tần số mỗi nhóm là tổng tần số
các ký tự trong nhóm.
Ký hiệu n : là số ký tự xuất hiện trong xâu.
Đầu tiên mảng c chứa n nhóm , đánh số theo thứ tự tự nhiên c[k] = k và ký tự thứ k thuộc
nhóm k : tren[k] = k

Với các nhóm mới ta sẽ dùng các chỉ số > n ( cho biết phu bằng n, mỗi lần thêm nhóm mới thì
tăng phu)
Vòng lặp, cho k ( là số nhóm chạy lùi từ n đến 2 sắp xếp lại các nhóm theo tần số giảm dần.
Lấy hai nhóm cuối cùng là c[k – 1] và c[k] gộp hai nhóm này thành một nhóm, đặt số hiệu nhóm
là một số nguyên mới, chẳng hạn là số phu
Vòng lặp i duyệt từng ký tự :
 Nếu ký tự kt[i] đang thuộc nhóm c[k – 1] ( tren[i] đang bằng c[k – 1]) thì cho ký tự đó
thuộc nhóm mới phu ( gán tren[i] bằng phu) và nối ký tự ‘0’ vào bên trái ma[i] ( mã số
của kt[i])


Nếu kỳ tự kt[i] đang thuộc nhóm c[k] ( tren[i] đang bằng c[k]) thì cho ký tự đó thuộc
nhóm mới phu ( gán tren[i] bằng phu) và nối ký tự ‘1’ vào bên trái ma[i] ( mã số của
kt[i])

Hết vòng lặp i.
 Gán tanso[phu] bằng tổng tần số của hai nhóm c[k – 1] và c[k]
 Gán c[k – 1] bằng phu ( có nghĩa là loại c[k-1] và c[k] ra khỏi mảng c, và đưa nhóm mới
phu vào mảng)
Hết vòng lặp k.
Ma[i] sẽ là mã số của ký tự thứ i
Trong một số trường hợp, có thể gặp hai ký tự trong đó ký tự này có tần số bé hơn ký tự kia
nhưng mã số lại ngắn hơn ( chẳng hạn khi đếm tần số bị tràn kiểu nguyên). Ta có thể điều chỉnh
lại bằng cách sắp xếp mảng ký tự theo tần số giảm dần và mảng mã theo độ dài tăng dần, rồi lấy
ma[i] dùng cho kt[i].

24


II. Code chương trình

3. Tổng quan các hàm










Hàm Khởi Đầu
Hàm Chỉ Số
Hàm Đếm
Hàm Sắp Đầu
Hàm Nối
Hàm Tạo Mã Số
Hàm Điều chỉnh
Hàm In Mã Số
Hàm main.

4. Triển khai các hàm bằng C

25


×