二叉樹的四種遍歷方法:先序,中序,後序,層序

李志成發表於2019-05-18
前序
中序
後續

始終在前面,不同的是 這個位置

前序遍歷

中序遍歷

二叉樹的四種遍歷方法:先序,中序,後序,層序

後序遍歷

二叉樹的四種遍歷方法:先序,中序,後序,層序

層序遍歷

二叉樹的四種遍歷方法:先序,中序,後序,層序

程式碼實現

基礎類

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/

相關文章