[php]递归和迭代两种方法实现 2021.07.24

4 篇文章 0 订阅

1.题目:

 2.解答

1)递归算法:
--思路: 比较左子树中的值比根节点的值不小,或 右子树中的值比根节点中的值不大,则返回 false
--代码实现

$this->doCheck($root, PHP_INT_MIN, PHP_INT_MAX);
 /**
    * 递归(recursion)的解决方案
    * php中最小数值和最大数值怎么表示?PHP_INT_MAXPHP_INT_MIN
     */
    function doCheck($root, $lowVal, $highVal) {
        if($root === null){
            return true;
        }

        // 适当的调试,帮助理解和编码
        //var_dump("01", $root->val, $lowVal, $highVal, "\n\n");

        // 一定注意判断下 $lowVal 和 $highVal 为 null的情况
        if(($root->val <= $lowVal)
        || ($root->val >= $highVal)){
            return false;
        }

        // 注意是取 逻辑的与
        return $this->doCheck($root->left, $lowVal, $root->val)
         && $this->doCheck($root->right, $root->val, $highVal);
    }


-- 注意点:
① php的最小值,最大值分别为 PHP_INT_MIN 和 PHP_INT_MAX
② php是弱语言,里边的 null == 0 会返回 true
③ 最后的 返回表达式里,上下边界的取值
return this->doCheck(this−>doCheck(root->left, $lowVal, $root->val)
&& this->doCheck(this−>doCheck(root->right, $root->val, $highVal);

2)迭代算法
--思路: 使用二叉树的中序遍历,因为是 二叉搜索树,中序遍历的结果应该是一个 升序序列。
-- 代码实现:

/**
    * 迭代(iteration)的解决方案: 中序遍历
    */
    function dieDaiCheck($root){
        if($root === null){
            return true;
        }

        // 栈数组
        $stack = array();
        $inOrder = null;
        // test 
        $loop = 0;
        while(!empty($stack) || $root != null){
            // test 
            $loop ++;
            while($root !== null){
                // 这里放置的是一个对象
                $stack[] = $root;
                $root = $root->left;
            }

            // 出栈
            $root = array_pop($stack);

            // 注意php是弱语言, 0 == null 会返回真
            if($inOrder !== null && $root->val <= $inOrder){
                return false;
            }

            $inOrder = $root->val;
            $root = $root->right;

        }

        return true;
    }

-- 注意点:
① 中序遍历的迭代算法中,使用数据结构 stack来实现,java中建议是 DeQueue,不建议已经过时的 Stack, php中数组表达一切,只是注意 array_pop代表弹栈操作
②php弱语言的性质还要注意
③ 二叉树中序遍历的模板注意背诵,左 * 右

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值