-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhuffman.js
More file actions
89 lines (77 loc) · 2.76 KB
/
huffman.js
File metadata and controls
89 lines (77 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class Node {
constructor(char, frequency) {
this.char = char;
this.frequency = frequency;
this.left = null;
this.right = null;
}
}
function buildHuffmanTree(text) {
const charFrequencyMap = {};
for (let char of text) {
if (charFrequencyMap[char] === undefined) {
charFrequencyMap[char] = 1;
} else {
charFrequencyMap[char]++;
}
}
console.log("Character frequencies:");
console.log(Object.entries(charFrequencyMap).map(([char, freq]) => `${char}: ${freq}`).join(", "));
const nodes = Object.entries(charFrequencyMap).map(([char, frequency]) => new Node(char, frequency));
let step = 1;
while (nodes.length > 1) {
nodes.sort((a, b) => a.frequency - b.frequency);
const left = nodes.shift();
const right = nodes.shift();
const merged = new Node(left.char + right.char, left.frequency + right.frequency);
merged.left = left;
merged.right = right;
nodes.push(merged);
console.log(`Step ${step++}: Merged ${left.char} (${left.frequency}) and ${right.char} (${right.frequency}) into ${merged.char}`);
}
return nodes[0];//возвращаем корень
}
function generateHuffmanCodes(node, prefix = '') {
const codes = {};
if (node) {
if (!node.left && !node.right) {
codes[node.char] = prefix || '0';//если префикс не опеределен то 0
console.log(`Assigned code ${codes[node.char]} to character '${node.char}'`);
} else {
Object.assign(codes, generateHuffmanCodes(node.left, prefix + '0'));
Object.assign(codes, generateHuffmanCodes(node.right, prefix + '1'));
}
}
return codes;
}
function encode(text, codes) {
let encodedText = '';
for (let char of text) {
encodedText += codes[char];
}
return encodedText;
}
function decode(encodedText, tree) {
let decodedText = '';
let currentNode = tree;
for (let bit of encodedText) {
if (bit === '0') {
currentNode = currentNode.left;
} else {
currentNode = currentNode.right;
}
if (!currentNode.left && !currentNode.right) {
decodedText += currentNode.char;
currentNode = tree;
}
}
return decodedText;
}
const text = 'abbcccddddeeeee';
console.log('Original Text:', text);
const huffmanTree = buildHuffmanTree(text);
const codes = generateHuffmanCodes(huffmanTree);
const encodedText = encode(text, codes);
const decodedText = decode(encodedText, huffmanTree);
console.log('Encoded Text:', encodedText);
console.log('Decoded Text:', decodedText);