2024年最新剑指Offer——二叉树_二叉树 jianzhioffer(2),Web前端音频面试题

最后

小编的一位同事在校期间连续三年参加ACM-ICPC竞赛。从参赛开始,原计划每天刷一道算法题,实际上每天有时候不止一题,一年最终完成了 600+:

凭借三年刷题经验,他在校招中很快拿到了各大公司的offer。

入职前,他把他的刷题经验总结成1121页PDF书籍,作为礼物赠送给他的学弟学妹,希望同学们都能在最短时间内掌握校招常见的算法及解题思路。

整本书,我仔细看了一遍,作者非常细心地将常见核心算法题和汇总题拆分为4个章节。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

而对于有时间的同学,作者还给出了他结合众多数据结构算法书籍,挑选出的一千多道题的解题思路和方法,以供有需要的同学慢慢研究。

    if(subTree == null)  
        return null;  
    if(subTree.leftChild == element || subTree.rightChild == element)
        //返回父结点地址  
        return subTree;  
    TreeNode p;
    // 先在左子树中找,如果左子树中没有找到,才到右子树去找  
    if((p = parent(subTree.leftChild, element)) != null)
        //递归在左子树中搜索  
        return p;  
    else  
        //递归在右子树中搜索  
        return parent(subTree.rightChild, element);  
}  
  
public TreeNode getLeftChildNode(TreeNode element){  
    return (element != null) ? element.leftChild : null;  
}  
  
public TreeNode getRightChildNode(TreeNode element){  
    return (element != null) ? element.rightChild : null;  
}  
  
public TreeNode getRoot(){  
    return root;
}  
  
//在释放某个结点时,该结点的左右子树都已经释放,  
//所以应该采用后续遍历,当访问某个结点时将该结点的存储空间释放  
public void destroy(TreeNode subTree){  
    //删除根为subTree的子树  
    if(subTree!=null){  
        //删除左子树  
        destroy(subTree.leftChild);  
        //删除右子树  
        destroy(subTree.rightChild);  
        //删除根结点  
        subTree=null;  
    }  
}  
  
public void traverse(TreeNode subTree){  
    System.out.println("key:"+subTree.key+"--name:"+subTree.data);;  
    traverse(subTree.leftChild);  
    traverse(subTree.rightChild);  
}  
  
//前序遍历  
public void preOrder(TreeNode subTree){  
    if(subTree!=null){  
        visted(subTree);  
        preOrder(subTree.leftChild);  
        preOrder(subTree.rightChild);  
    }  
}  
  
//中序遍历  
public void inOrder(TreeNode subTree){  
    if(subTree!=null){  
        inOrder(subTree.leftChild);  
        visted(subTree);  
        inOrder(subTree.rightChild);  
    }  
}  
  
//后续遍历  
public void postOrder(TreeNode subTree) {  
    if (subTree != null) {  
        postOrder(subTree.leftChild);  
        postOrder(subTree.rightChild);  
        visted(subTree);  
    }  
}  
  
//前序遍历的非递归实现  
public void nonRecPreOrder(TreeNode p){  
    Stack<TreeNode> stack=new Stack<TreeNode>();  
    TreeNode node=p;  
    while(node!=null||stack.size()>0){  
        while(node!=null){  
            visted(node);  
            stack.push(node);  
            node=node.leftChild;  
        }  
        while(stack.size()>0){  
            node=stack.pop();  
            node=node.rightChild;  
        }   
    }  
}  
  
//中序遍历的非递归实现  
public void nonRecInOrder(TreeNode p){  
    Stack<TreeNode> stack =new Stack<BinaryTree.TreeNode>();  
    TreeNode node =p;  
    while(node!=null||stack.size()>0){  
        //存在左子树  
        while(node!=null){  
            stack.push(node);  
            node=node.leftChild;  
        }  
        //栈非空  
        if(stack.size()>0){  
            node=stack.pop();  
            visted(node);  
            node=node.rightChild;  
        }  
    }  
}  
  
//后序遍历的非递归实现  
public void noRecPostOrder(TreeNode p){  
    Stack<TreeNode> stack=new Stack<BinaryTree.TreeNode>();  
    TreeNode node =p;  
    while(p!=null){  
        //左子树入栈  
        for(;p.leftChild!=null;p=p.leftChild){  
            stack.push(p);  
        }  
        //当前结点无右子树或右子树已经输出  
        while(p!=null&&(p.rightChild==null||p.rightChild==node)){  
            visted(p);  
            //纪录上一个已输出结点  
            node =p;  
            if(stack.empty())  
                return;  
            p=stack.pop();  
        }  
        //处理右子树  
        stack.push(p);  
        p=p.rightChild;  
    }  
}  
public void visted(TreeNode subTree){  
    subTree.isVisted=true;  
    System.out.println("key:"+subTree.key+"--name:"+subTree.data);;  
}  
  
  
/**
 * 二叉树的节点数据结构
 * @author WWX
 */  
private class  TreeNode{
    private int key = 0;
    private String data = null;  
    private boolean isVisted = false;
    private TreeNode leftChild = null;
    private TreeNode rightChild = null;  
      
    public TreeNode(){}  
      
    /**
     * @param key  层序编码
     * @param data 数据域
     */  
    public TreeNode(int key,String data){  
        this.key = key;  
        this.data = data;  
        this.leftChild = null;  
        this.rightChild = null;  
    }  
}  
  
//测试  
public static void main(String[] args) {  
    BinaryTree bt = new BinaryTree();  
    bt.createBinTree(bt.root);  
    System.out.println("the size of the tree is " + bt.size());  
    System.out.println("the height of the tree is " + bt.height());  
      
    System.out.println("***递归实现****(前序遍历)[ABDECF]遍历*****************");  
    bt.preOrder(bt.root);  
      
    System.out.println("***递归实现****(中序遍历)[DBEACF]遍历*****************");  
    bt.inOrder(bt.root);  
     
    System.out.println("***递归实现****(后序遍历)[DEBFCA]遍历*****************");  
    bt.postOrder(bt.root);  
      
    System.out.println("***非递归实现****(前序遍历)[ABDECF]遍历*****************");  
    bt.nonRecPreOrder(bt.root);  
      
    System.out.println("***非递归实现****(中序遍历)[DBEACF]遍历*****************");  
    bt.nonRecInOrder(bt.root);  
      
    System.out.println("***非递归实现****(后序遍历)[DEBFCA]遍历*****************");  

总结

面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。

还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

前端面试题汇总

JavaScript

前端资料汇总

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值