php二叉树遍历递归,4.2 数据结构(PHP实现) -- 二分搜索树的遍历(递归实现)...

1. 遍历原则前序遍历:先遍历当前结点,再遍历当前结点的左儿子,最后遍历当前结点的右儿子

中序遍历:先遍历当前结点的左儿子,再遍历当前结点,最后遍历当前结点的右儿子

后续遍历:先遍历当前结点的左儿子,再遍历当前结点的右儿子,最后遍历当前结点

2. 前序遍历示意图

bVcIcw4

3. 中序遍历示意图

bVcIczR

4. 后序遍历示意图

bVcIcBI

5. 二分搜索树的递归遍历实现<?php

namespace TreeBundle;

use ArrayBundle\BaseArray;

use StackBundle\BaseStack;

class BaseBinaryTree

{

public function __construct()

{

$this->rootNode = null;

$this->size = 0;

}

/**

* 二叉树的根节点

* @var Node

*/

protected $rootNode;

/**

* 获取根节点

* @return Node

*/

public function getRootNode(): Node

{

return $this->rootNode;

}

/**

* 二叉树的个数

* @var int

*/

protected $size;

/**

* 获取二叉树的元素个数

* @return int

*/

public function getSize(): int

{

return $this->size;

}

/**

* 判断是否为空

* @return bool

*/

public function isEmpty(): bool

{

return $this->size == 0;

}

/**

* 插入结点

* @param mixed $value

* @return void

*/

public function add($value): void

{

// 如果不存在根节点就插入根节点

if (is_null($this->rootNode)) {

$this->rootNode = new Node($value);

$this->size;

return;

} else {

$this->addChild($value, $this->rootNode);

return;

}

}

/**

* 插入儿子结点

* @param mixed $value

* @param Node|null $parentNode

*/

private function addChild($value, ?Node $parentNode): void

{

if (bccomp($parentNode->getValue(), $value) > 0) {

// 左儿子

if (is_null($parentNode->getLeftChild())) {

$parentNode->setLeftChild(new Node($value));

$this->size++;

return;

} else {

$this->addChild($value, $parentNode->getLeftChild());

}

} elseif (bccomp($parentNode->getValue(), $value) < 0) {

// 右儿子

if (is_null($parentNode->getRightChild())) {

$parentNode->setRightChild(new Node($value));

$this->size++;

return;

} else {

$this->addChild($value, $parentNode->getRightChild());

}

} else {

return;

}

}

const TRAVERSAL_PREORDER = 1; // 先序遍历

const TRAVERSAL_INORDER = 2; // 中序遍历

const TRAVERSAL_POSTORDER = 3; // 后序遍历

/**

* 遍历二叉树

* @param int $traversalType

* @return string

*/

public function traversal(int $traversalType = 1): string

{

$result = '';

switch ($traversalType) {

case self::TRAVERSAL_PREORDER:

$this->preorderTraversal($result, $this->rootNode);

break;

case self::TRAVERSAL_INORDER:

$this->inorderTraversal($result, $this->rootNode);

break;

case self::TRAVERSAL_POSTORDER:

$this->postorderTraversal($result, $this->rootNode);

break;

default:

break;

}

return $result;

}

/**

* 先序遍历

* @param string $result 结果值

* @param Node|null $node 结点

* @return void

*/

protected function preorderTraversal(string &$result, ?Node $node): void

{

if (is_null($node)) return;

// 拼接

if ($result != '') $result .= ' -> ';

// 先遍历当前节点

$result .= $node->getValue();

// 再遍历左儿子

$this->preorderTraversal($result, $node->getLeftChild());

// 在遍历右儿子

$this->preorderTraversal($result, $node->getRightChild());

return;

}

/**

* 中序遍历

* @param string $result 结果值

* @param Node|null $node 结点

* @return void

*/

public function inorderTraversal(string &$result, ?Node $node): void

{

if (is_null($node)) return;

// 先遍历左儿子

$this->inorderTraversal($result, $node->getLeftChild());

// 拼接

if ($result != '') $result .= ' -> ';

// 再获取当前结点

$result .= $node->getValue();

// 在遍历右儿子

$this->inorderTraversal($result, $node->getRightChild());

return;

}

/**

* 后序遍历

* @param string $result 结果值

* @param Node|null $node 结点

* @return void

*/

public function postorderTraversal(string &$result, ?Node $node): void

{

if (is_null($node)) return;

// 先遍历左儿子

$this->postorderTraversal($result, $node->getLeftChild());

// 在遍历右儿子

$this->postorderTraversal($result, $node->getRightChild());

// 拼接

if ($result != '') $result .= ' -> ';

// 再获取当前结点

$result .= $node->getValue();

return;

}

}

6. demo<?php

// composer自动加载

require_once __DIR__ . '/../../vendor/autoload.php';

// 获取一个二分搜索树

$tree = new TreeBundleBaseBinaryTree();

// 插入结点

$tree->add(10);

$tree->add(5);

$tree->add(15);

$tree->add(1);

$tree->add(0);

$tree->add(2);

$tree->add(9);

$tree->add(8);

$tree->add(11);

$tree->add(12);

$tree->add(19);

$tree->add(18);

$tree->add(29);

$tree->add(16);

$tree->add(17);

// 前序遍历

echo $tree->traversal(TreeBundleBaseBinaryTree::TRAVERSAL_PREORDER). PHP_EOL;

// 中序遍历

echo $tree->traversal(TreeBundleBaseBinaryTree::TRAVERSAL_INORDER). PHP_EOL;

// 后续遍历

echo $tree->traversal(TreeBundleBaseBinaryTree::TRAVERSAL_POSTORDER). PHP_EOL;

打印结果:10 -> 5 -> 1 -> 0 -> 2 -> 9 -> 8 -> 15 -> 11 -> 12 -> 19 -> 18 -> 16 -> 17 -> 29

0 -> 1 -> 2 -> 5 -> 8 -> 9 -> 10 -> 11 -> 12 -> 15 -> 16 -> 17 -> 18 -> 19 -> 29

0 -> 2 -> 1 -> 8 -> 9 -> 5 -> 12 -> 11 -> 17 -> 16 -> 18 -> 29 -> 19 -> 15 -> 10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值