关于PHP里二叉树如何构建请阅读:PHP二叉树之构建二叉树,本文将在上文的基础上,继续介绍二叉树的前序、中序、后序三种遍历节点的方法。
将一个树节点的根节点称为中,左节点为左,右节点为右,前中后序的定义的就看 中 的位置:
- 前序遍历:中左右
- 中序遍历:左中右
- 后序遍历:左右中
请看代码:
class Solution {
/**
* 144. 二叉树的前序遍历-DLR
*
* 每次先得到当前节点的val,然后再处理左节点,如果左节点还有子左节点继续深度遍历。
*
* @param TreeNode $root
* @return Integer[]
*/
function preorderTraversal($root) {
// 无脑递归法
// return $this->traversal($root);
// 迭代法
return $this->iterateTravsal($root);
}
// 前序-递归法
function traversal($node, $result = []) {
if ($node->val === null) return $result;
$result[] = $node->val;
$result = $this->traversal($node->left, $result);
$result = $this->traversal($node->right, $result);
return $result;
}
// 前序-迭代法
function iterateTravsal($node) {
$result = [];
$stack = new SplStack;
$stack->push($node);
while (!$stack->isEmpty()) {
$cur = $stack->pop();
$result[] = $cur->val;
// 右节点先入栈
if ($cur->right) {
$stack->push($cur->right);
}
// 左节点后入栈(因为后入先出,下一个循环要左节点先出)
if ($cur->left) {
$stack->push($cur->left);
}
}
return $result;
}
/**
* 中序遍历-LDR
*
* 循环时看当前节点有无左节点,有左则继续深度遍历找子左节点,直到找不到左子节点才开始取数据
*
* @param TreeNode $root
* @return Integer[]
*/
function inorderTraversal($root) {
$result = [];
$stack = new SplStack;
$cur = $root;
while ($cur !== null || !$stack->isEmpty()) {
if ($cur !== null) {
$stack->push($cur); // 当前有效节点存入栈
$cur = $cur->left; // 如果左节点不是NULL继续往下找
} else {
// 遍历左节点到底层了
$cur = $stack->pop();
$result[] = $cur->val; // 中间节点
$cur = $cur->right;
}
}
return $result;
}
/**
* 145. 二叉树的后序遍历-LRD
*
* 如果延续常规的思路会发现遍历有一点麻烦,我们回到前序发现,在循环中换一下循环内的入栈顺序
* 结果将变成中右左,然后我们将结果数组翻转一下,就达到了左右中的正确结果
*
* @param TreeNode $root
* @return Integer[]
*/
function postorderTraversal($root) {
$result = [];
$stack = new SplStack;
$stack->push($root);
while (!$stack->isEmpty()) {
$cur = $stack->pop();
$result[] = $cur->val;
// 左节点先入栈
if ($cur->left) {
$stack->push($cur->left);
}
// 右节点后入栈(因为后入先出,下一个循环要右节点先出)
if ($cur->right) {
$stack->push($cur->right);
}
}
return array_reverse($result);
}
}
$solution = new Solution;
// 构建一棵二叉树,BinaryTree类看本文开头
$tree = new BinaryTree([3,1,2]);
print_r($solution->preorderTraversal($tree->root)); // 前序遍历,结果 [3,1,2]
print_r($solution->inorderTraversal($tree->root)); // 中序遍历,结果 [1,3,2]
print_r($solution->postorderTraversal($tree->root)); // 后序遍历,结果 [1,2,3]
以上是三种遍历的写法,每种写法都有点小变化,大家用的时候要注意哦~