【PHP版二叉樹遍歷】深度優先(前序中序後序)和廣度優先

<?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
相關文章
相關標籤/搜索