<?php /** * 深度遍歷 * Class DepthTraversal */ class DepthTraversal { public function notRecursive($root) { echo "深度優先遍歷-前序-非遞歸"; $this->preOrder($root); echo "\r\n"; echo "深度優先遍歷-中序-非遞歸"; $this->inOrder($root); echo "\r\n"; echo "深度優先遍歷-後序-非遞歸"; $this->postOrder($root); echo "\r\n"; } public function recursive($root) { echo "深度優先遍歷-前序-遞歸"; $this->pre_order($root); echo "\r\n"; echo "深度優先遍歷-中序-遞歸"; $this->in_order($root); echo "\r\n"; echo "深度優先遍歷-後序-遞歸"; $this->post_order($root); echo "\r\n"; } // 前序非遞歸遍歷 public function preOrder($root) { $stack = array(); array_push($stack, $root); while (!empty($stack)) { $center_node = array_pop($stack); echo $center_node->value . " "; if ($center_node->right != null) { array_push($stack, $center_node->right); } if ($center_node->left != null) { array_push($stack, $center_node->left); } } } // 前序遞歸遍歷 public function pre_order($root) { if ($root != null) { echo $root->value . " "; if ($root->left != null) { $this->pre_order($root->left); } if ($root->right != null) { $this->pre_order($root->right); } } } // 中序非遞歸遍歷 public function inOrder($root) { $stack = array(); $current_node = $root; while (!empty($stack) || $current_node != null) { while ($current_node != null) { array_push($stack, $current_node); $current_node = $current_node->left; } $current_node = array_pop($stack); echo $current_node->value . " "; $current_node = $current_node->right; } } // 中序遞歸遍歷 public function in_order($root) { if ($root != null) { if ($root->left != null) { $this->in_order($root->left); } echo $root->value . " "; if ($root->right != null) { $this->in_order($root->right); } } } // 後序非遞歸遍歷 public function postOrder($root) { $stack = array(); $out_stack = array(); array_push($stack, $root); while (!empty($stack)) { $center_node = array_pop($stack); array_push($out_stack, $center_node); if ($center_node->left != null) { array_push($stack, $center_node->left); } if ($center_node->right != null) { array_push($stack, $center_node->right); } } while (!empty($out_stack)) { $center_node = array_pop($out_stack); echo $center_node->value . " "; } } // 後序遞歸遍歷 public function post_order($root) { if ($root != null) { if ($root->left != null) { $this->post_order($root->left); } if ($root->right != null) { $this->post_order($root->right); } echo $root->value . " "; } } } /** * 廣度優先遍歷 * Class BreadthTraversal */ class BreadthTraversal { public function notRecursive($root) { if ($root == null) { return; } $node = $root; $queue = array(); array_push($queue, $node); while (!empty($queue)) { $node = array_shift($queue); echo $node->value . " "; if ($node->left != null) { array_push($queue, $node->left); } if ($node->right != null) { array_push($queue, $node->right); } } } public function recursive($root) { // 空樹或層級不合理 $depth = $this->getDepth($root); if ($root == null || $depth < 1) { return; } for ($i = 1; $i <= $depth; $i++) { $this->printTree($root, $i); } } function getDepth($root) { if ($root == null) { return 0; } if ($root->left == null && $root->right == null) { return 1; } $left_depth = $this->getDepth($root->left); $right_depth = $this->getDepth($root->right); return ($left_depth > $right_depth ? $left_depth : $right_depth) + 1; } public function printTree($root, $level) { if ($root == null || $level < 1) { return; } if ($level == 1) { echo $root->value . " "; } $this->printTree($root->left, $level - 1); $this->printTree($root->right, $level - 1); } } /** * 二叉樹節點 */ class BinaryTreeNode { public $value; public $left; public $right; } // 構造一個二叉樹 /** * A * B C * D E F G */ $a = new BinaryTreeNode(); $b =new BinaryTreeNode(); $c =new BinaryTreeNode(); $d =new BinaryTreeNode(); $e =new BinaryTreeNode(); $f =new BinaryTreeNode(); $g =new BinaryTreeNode(); $a->value = 'A'; $b->value = 'B'; $c->value = 'C'; $d->value = 'D'; $e->value = 'E'; $f->value = 'F'; $g->value = 'G'; $a->left = $b; $a->right = $c; $b->left = $d; $b->right = $e; $c->left = $f; $c->right = $g; $dt = new DepthTraversal(); $dt->notRecursive($a); $dt->recursive($a); echo "\r\n"; $bt = new BreadthTraversal(); echo "廣度優先遍歷-非遞歸"; $bt->notRecursive($a); echo "\r\n"; echo "廣度優先遍歷-遞歸"; $bt->recursive($a);
深度優先遍歷-前序-非遞歸A B D E C F G 深度優先遍歷-中序-非遞歸D B E A F C G 深度優先遍歷-後序-非遞歸D E B F G C A 深度優先遍歷-前序-遞歸A B D E C F G 深度優先遍歷-中序-遞歸D B E A F C G 深度優先遍歷-後序-遞歸D E B F G C A 廣度優先遍歷-非遞歸A B C D E F G 廣度優先遍歷-遞歸A B C D E F G