public static function buildTree($s) { $t = new Tree(); $seenSymbols = array(); $pq = new PriorityQueue(); // Add leaf nodes for each symbol to the priority queue. for ($i = 0; $i < strlen($s); ++$i) { $c = $s[$i]; if (array_key_exists($c, $seenSymbols)) { continue; } $occurrences = 0; for ($j = $i; $j < strlen($s); ++$j) { if ($s[$j] != $c) { continue; } $occurrences++; } $node = new Node($c, $occurrences); $pq->enqueue($node); $t->leaves[$c] = $node; $seenSymbols[$c] = true; } if ($pq->size() == 0) { return $t; } // While there is more than one node left in the priority queue: while ($pq->size() > 1) { // Remove the two nodes of highest priority (lowest probability). $node1 = $pq->dequeue(); $node2 = $pq->dequeue(); // Create a new internal node with the two nodes as children with // p_total = p_1 + p_2 $newNode = new Node(null, $node1->weight + $node2->weight); $newNode->left = $node1; $newNode->right = $node2; $node1->parent = $newNode; $node2->parent = $newNode; // Add the new node to the queue. $pq->enqueue($newNode); } // The final node in the priority queue is the root. $t->root = $pq->dequeue(); return $t; }