1. Linear Scan Merge
Intuition
Maintain a dynamic list of active trees. Repeatedly scan linearly across all elements to find and remove the two minimum frequency nodes, merge them, and append the parent.
Algorithm
- Step 1: Create leaf nodes for each character and place them in an array.
- Step 2: Loop N-1 times: scan the array to locate the indices of the two nodes with minimal frequencies.
- Step 3: Remove those two nodes, create a parent node with left and right children and summed frequency.
- Step 4: Add the parent back to the array.
- Step 5: Perform preorder traversal on the final remaining root node to generate binary codes.
#include <iostream>#include <vector>#include <string>#include <algorithm> using namespace std; struct Node { char data; int freq; Node *left, *right; Node(char d, int f) : data(d), freq(f), left(nullptr), right(nullptr) {}}; class Solution { void preorder(Node* root, string code, vector<string>& ans) { if (!root) return; if (!root->left && !root->right) { ans.push_back(code.empty() ? "0" : code); return; } preorder(root->left, code + "0", ans); preorder(root->right, code + "1", ans); }public: vector<string> huffmanCodes(string S, vector<int>& f, int N) { vector<Node*> nodes; for (int i = 0; i < N; ++i) nodes.push_back(new Node(S[i], f[i])); while (nodes.size() > 1) { int min1 = 0; for (int i = 1; i < (int)nodes.size(); ++i) { if (nodes[i]->freq < nodes[min1]->freq) min1 = i; } Node* leftNode = nodes[min1]; nodes.erase(nodes.begin() + min1); int min2 = 0; for (int i = 1; i < (int)nodes.size(); ++i) { if (nodes[i]->freq < nodes[min2]->freq) min2 = i; } Node* rightNode = nodes[min2]; nodes.erase(nodes.begin() + min2); Node* parent = new Node(', leftNode->freq + rightNode->freq);, leftNode->freq + rightNode->freq); parent->left = leftNode; parent->right = rightNode; nodes.push_back(parent); } vector<string> ans; if (!nodes.empty()) preorder(nodes[0], "", ans); return ans; }}; int main() { Solution sol; string S = "abcdef"; vector<int> f = {5, 9, 12, 13, 16, 45}; vector<string> codes = sol.huffmanCodes(S, f, S.size()); cout << "Huffman Codes (Preorder):" << endl; for (const string& code : codes) { cout << code << " "; } cout << endl; return 0;}Time & Space Complexity
- Time complexity:
O(N^2) - Space complexity:
O(N)