二叉树深度计算

今天面试,被问到了二叉树的深度计算问题。

一听到这个问题,第一反应是大学被写烂了的基本数据结构问题。

然而我已经毕业3年,没写算法很久,手都生了。但是呢,不能说生了就只对面试官说思路吧,于是还是不假思索的立马拿起笔,写了起来,毕竟这是一个基本的数据结构题目。

首先立马写了一个二叉树结构。

public class BinaryTree{
        BinaryTree lChild, rChild;
        int value;
    }

一写出来,立马有了感觉。顺势写了计算方法

public int computeTreeDepth(BinaryTree binaryTree){
        if(binaryTree.lChild == null && binaryTree.rChild == null){
            return 1;
        }
        int lDepth = computeTreeDepth(binaryTree.lChild);
        int rDepth = computeTreeDepth(binaryTree.rChild);
        return Math.max(lDepth, rDepth);
    }

然后就给面试官看了。

面试官问我有感觉哪里不对吗?哎,只怪我太久没写算法题了,连这个基本的深度计算,都出现简单失误。更可气的是在当时的紧张环境下,我竟然没有发现哪里问题。后来经过面试官提醒,也终于改了过来。

    public int computeTreeDepth(BinaryTree binaryTree){
        if(binaryTree == null){
            return 0;
        }
        if(binaryTree.lChild == null && binaryTree.rChild == null){
            return 1;
        }
        int lDepth = computeTreeDepth(binaryTree.lChild) + 1;
        int rDepth = computeTreeDepth(binaryTree.rChild) + 1;
        return Math.max(lDepth, rDepth);
    }

此时我的心里一万个对自己无语,竟然在面试的时候出现这么大的失误(不过也只怪我平常自从毕业就很少去深入写算法题了,以后一定要注意)

这个时候,面试官说这是递归实现,写一下非递归实现。

当时心里无语的我顿时一塞,非递归实现,然后一想,也简单。然后就屁颠屁颠的开始写起来。写着写着我发现,情况似乎不是我想的这么简单。随着时间的深入,我的心里变得异常紧张,结果硬是在那几分钟没想出来。此刻真是深深的鄙视自己,无论是什么原因让我当时的大脑短路了,终究的结果是我没写出来非递归实现。之后面试官委婉的叫我下去在思考这个问题吧。

总结一下:

问题:自己当时太想着展现自己,导致自己的思路太过紧凑反而限制了我的思维,导致这个简单的问题也写出漏洞,甚至连非递归实现最后没编写出来。

对自己的思考:

1.作为程序猿,平常还是要多锻炼自己的算法编写习惯,多去思考。只有这样才可以在面试中对算法题有一个较好的把控。

2.面试的时候心态要放平稳,不能心浮气躁,导致自己出现各种临时小问题。因为对方只会看结果。

回来了,自己重新写了一遍二叉树的深度计算实现,果然很简单。记录一下吧,就当是自己前进的路上的一个绊脚石,也希望自己在每一次总结之后能进步自己。

多思考,多学习,放平心态,去面对每一个新技术,新思维。

下面贴代码

二叉树深度计算的递归实现:

    public int computeTreeDepth(BinaryTree binaryTree){
        if(binaryTree == null){
            return 0;
        }
        return Math.max(computeTreeDepth(binaryTree.lChild), computeTreeDepth(binaryTree.rChild)) + 1;
    }

二叉树深度计算的非递归实现:

首先想到是直接遍历,如果是直接遍历那自然就有两种思路,广度优先和深度优先。

先说广度优先,因为是遍历下一层意味着上一层都已遍历,先进先出,采用队列实现:

    public int computeTreeDepth(BinaryTree binaryTree){
        //实例化队列
        Queue<BinaryTree> mVisitList = new LinkedList<>();
        BinaryTree tmp;
        int depth = 0, lengthTmp;
        if(binaryTree == null){
            //根为空,直接返回0
            return 0;
        }
        //将根加入队列
        mVisitList.offer(binaryTree);
        while (!mVisitList.isEmpty()){
            //只要队列不为空,说明新的一层数据不为空,且已经加到队列,深度+1
            depth ++;
            //遍历该层到所有数据,将他们出队,并附带把所有下一层到数据都加进来(如果有的话)
            lengthTmp = mVisitList.size();
            while (lengthTmp -- > 0){
                tmp = mVisitList.poll();
                if(tmp.lChild != null){
                    mVisitList.offer(tmp.lChild);
                }
                if(tmp.rChild != null){
                    mVisitList.offer(tmp.rChild);
                }
            }
        }
        return depth;
    }

然后深度优先,因为是深度遍历那肯定是先进后出,采用栈实现,然后遍历思路是先遍历当前节点的左子树,没有左子树到情况在遍历右子树:

    public int computeTreeDepth(BinaryTree binaryTree){
        //实例化栈
        Stack<BinaryTree> mVisitList = new Stack<>();
        BinaryTree tmp = binaryTree;
        int depth = 0;//遍历过程中到最大深度
        while (tmp != null){
            if(tmp.lChild != null || tmp.rChild != null){
                //如果有子树,将当前节点入栈,且更新最大深度
                mVisitList.push(tmp);
                depth = Math.max(depth, mVisitList.size());
                //因为是左子树优先,所以深度遍历下一个子节点的时候,优先左子树
                tmp = tmp.lChild != null ? tmp.lChild : tmp.rChild;
                continue;
            }
            //当前节点没有子树,直接更新最大深度(访问到当前节点到深度是栈的深度+1)
            depth = Math.max(depth, mVisitList.size() + 1);
            //此时回溯去找右子树
            while (!mVisitList.isEmpty()){
                if(mVisitList.peek().rChild != null && mVisitList.peek().rChild != tmp){
                    //如果栈顶节点的右子树不为空,且栈顶节点的右子树不等于正在访问的节点,访问右子树
                    tmp = mVisitList.peek().rChild;
                    break;
                }
                //说明当前栈顶节点的右子树为空,直接出栈,继续回溯
                // 且要更新当前节点,用于记录当前正在回溯的节点,避免死循环回溯
                tmp = mVisitList.pop();
            }
        }
        return depth;
    }

好了,上面就是二叉树的实现,自己写了几个测试用例没出现问题。但是不能保证完全没问题,有问题的话或者可以优化的欢迎留言交流,一起学习进步。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值