前序 | 中 | 左 | 右 |
---|---|---|---|
中序 | 左 | 中 | 右 |
後續 | 左 | 右 | 中 |
左
始終在右
前面,不同的是 中
這個位置
前序遍歷
中序遍歷
後序遍歷
層序遍歷
程式碼實現
基礎類
class TreeNode
{
public $left = null;
public $right = null;
public $parent = null;
public $value = null;
public function __construct($value)
{
$this->value = $value;
}
public function setLeft(TreeNode $node)
{
$this->left = $node;
$this->left->parent = $this;
}
public function setRight(TreeNode $node)
{
$this->right = $node;
$this->right->parent = $this;
}
public function __toString()
{
return (string)$this->value;
}
}
$a = new TreeNode('a');
$b = new TreeNode('b');
$c = new TreeNode('c');
$d = new TreeNode('d');
$e = new TreeNode('e');
$f = new TreeNode('f');
$g = new TreeNode('g');
$h = new TreeNode('h');
$i = new TreeNode('i');
$j = new TreeNode('j');
$k = new TreeNode('k');
$a->setLeft($b);
$a->setRight($c);
$b->setLeft($d);
$b->setRight($e);
$d->setLeft($h);
$d->setRight($i);
$e->setRight($j);
$c->setLeft($f);
$c->setRight($g);
$f->setRight($k);
遍歷實現
class Tree
{
public $root;
public function __construct(TreeNode $root)
{
$this->root = $root;
}
public static function preorder($node)
{
if (! ($node instanceof TreeNode)) {
return [];
}
return array_merge([$node], self::preorder($node->left), self::preorder($node->right));
}
public static function inorder($node)
{
if (! ($node instanceof TreeNode)) {
return [];
}
return array_merge(self::inorder($node->left), [$node], self::inorder($node->right));
}
public static function postorder($node)
{
if (! ($node instanceof TreeNode)) {
return [];
}
return array_merge(self::postorder($node->left), self::postorder($node->right), [$node]);
}
// 佇列實現 層序遍歷,先把根放進去,然後把左節點,右節點放進去
public static function levelorder($node)
{
$data = [];
if (! ($node instanceof TreeNode)) {
return $data;
}
$queue = [$node]; // 臨時處理佇列, 把開始節點放進佇列
while (! empty($queue)) {
$node = array_shift($queue); // 出隊
$data[] = $node;
$node->left && array_push($queue, $node->left);
$node->right && array_push($queue, $node->right);
}
return $data;
}
// 陣列 下標方式
public static function arrayLevelOrder($node)
{
$data = [];
if (! ($node instanceof TreeNode)) {
return $data;
}
$data = [$node];
$index = 0; // 陣列開頭開始,遍歷陣列每一個元素的左右節點,新增在陣列後面
while (count($data) > $index)
{
$node = $data[$index];
$node->left && ($data[] = $node->left);
$node->right && ($data[] = $node->right);
++$index;
}
return $data;
}
}
// 前序:a,b,d,h,i,e,j,c,f,k,g
echo "前序:", implode(',', Tree::preorder($tree->root)), "\n";
// 中序:h,d,i,b,e,j,a,f,k,c,g
echo "中序:", implode(',', Tree::inorder($tree->root)), "\n";
// 後序:h,i,d,j,e,b,k,f,g,c,a
echo "後序:", implode(',', Tree::postorder($tree->root)), "\n";
// 層序:a,b,c,d,e,f,g,h,i,j,k
echo "層序:", implode(',', Tree::levelorder($tree->root)), "\n";
// 層序:a,b,c,d,e,f,g,h,i,j,k
echo "層序:", implode(',', Tree::arrayLevelOrder($tree->root)), "\n";
參考:二叉樹的四種遍歷方法筆記
我的個人部落格:http://worthly.cn/