二叉树遍历主要有三种:先序遍历(根左右),中序遍历(左根右)和后序遍历(左右根),再加一个层次遍历(按层从左到右)
这三种方法又有递归和非递归的,递归的很简单,非递归的却很难。
递归:
先序:
val;
preorder($root->left);
preorder($root->right);
}
}
?>
中序:
left);
print $root->val;
inorder($root->right);
}
}
?>
后序:
left);
postorder($root->right);
print $root->val;
}
}
?>
非递归方法:
先序:
对于一个节点:1)输出该节点,将该节点入栈2)判断其左节点是否为空,若为空,则出栈,然后将右节点变成当前节点;若不为空,则将左节点变成当前节点。3)当节点为空,栈也为空时,结束遍历。
function preorder($root){
$array=array();
$p=$root;
while($p!=null||count($array)!=0){
while($p!=null){
print $p->val;
array_push($array,$p);
$p=$p->left;
}
if(count($array)!=0){
$p=$array[count($array)-1];
array_pop($array);
$p=$p->right;
}
}
}
现在回来看看这个先序遍历写的什么玩意,明明很简单
function preOrder($root) {
if ($root == null) {
return;
}
$arrNode = array();
array_push($arrNode , $root);
while (!empty($arrNode)) {
$node = array_pop($arrNode);
print $node->val;
if ($node->right !== null) {
array_push($arrNode , $node->right);
}
if ($node->left !== null) {
array_push($arrNode , $node->left);
}
}
}
中序:
对于一个节点:1)将该节点入栈。2)判断其左节点是否为空,若为空,则出栈,输出该节点,然后将右节点变成当前节点;若不为空,则将左节点变成当前节点。3)当节点为空,栈也为空时,结束遍历。
function inorder($root){
$array=array();
$p=$root;
while($p!=null||count($array)!=0){
while($p!=null){
array_push($array,$p);
$p=$p->left;
}
if(count($array)!=0){
$p=$array[count($array)-1];
print $p->val;
array_pop($array);
$p=$p->right;
}
}
}
后序:(最难!)
对于一个节点:1)将该节点入栈。2)判断其左节点和右节点是否为空,若为空,则出栈,输出该节点;若其中有一个不为空,但是输出过了,则输出该节点;若其中有一个不为空,但是没有输出过,则将右孩子和左孩子一次入栈,出栈的时候就可以保证左右根的顺序;栈顶作为下一个当前节点3)当节点为空,栈也为空时,结束遍历。
function postorder($root){
$array=array();
array_push($array,$root);
$pre=null;
while(count($array)!=0){
$p=$array[count($array)-1];
if(($p->left==null&&$p->right==null)||($pre!=null&&($pre==$p->left||$pre==$p->right))){
print $p->val;
array_pop($array);
$pre=$p;
}
else{
if($p->right!=null){
array_push($array,$p->right);
}
if($p->left!=null){
array_push($array,$p->left);
}
}
}
}
层次遍历
可以仿照层次遍历来获取二叉树的宽度,也就是二叉树每层的节点数最多的数量。
val;
if ($node->left != null) {
array_push($arrVal, $node->left);
}
if ($node->right != null) {
array_push($arrVal, $node->right);
}
}
}