算法之:树和二叉树常见算法

背景:在一些大公司,包括面试过程中,对一些常见的算法要求还是比较多的。书、二叉树、红黑树,被问比较多的一些,接下来,我将整理一些常见的算法,以供大家参考。

第一题:遍历二叉树的高度

解释:二叉树是一种有规则的树,所以在遍历的时候,递归使用的比较多。(关于递归,不太了解的可以百度一下递归算法)

public class TreeNode {

public TreeNode left;

public TreeNode right;

int val;

}

public int getTreeMaxHeight(TreeeNode node) {

        if(node==null)

        return 0;

//遍历左边和右边的子节点高度,求max,然后加上root(1),

return 1+Math.max(getTreeMaxHeight(node.left),getTreeMaxHeight(node.righte));

}

第二题:二叉树中的最大路径和

public class TreeNode {

public TreeNode left;

public TreeNode right;

int val;

}

public class Solution {

int maxnum=0;

public static void main() {

Solution  action=new Solution  ();

action.DFS();

System.out.printf(maxnum);

}

//遍历

public int DFS(TreeNode node)

{

        if(node==null)

     retrun 0;

int left=Math.max(node.left,0);

int right=Math.max(node.right,0);

maxnum=Math.max(maxnum,node.val+left+right);

return node.val+Math.max(left,right);

}

第三题:求某个节点以双亲子节点的最大和。(满树)

int max=0;

public int dfs(TreeNode node) {

if(node==null) {

        return 0;

}

if(node.left!=null&&node.right!=null)

{

        int sum=node.val+node.left.val+node.right.val;

max=        Math.max(max,sum);

}

dfs(node.left);

dfs(node.right);

return 0;

}

第三题:二叉树的遍历

1.采用递归方式

前序、后序、中序遍历,只是输出位置不同

public void  dfs(Tree tree)

{

        if(tree==null)

                return;

                system.out.printf(tree.val);//前序遍历的结果

                dfs(tree.left)

                system.out.printf(tree.val);//中序遍历的结果

                dfs(tree.right);

                system.out.printf(tree.val);//后序遍历的结果

}

2.前序遍历:非递归

public void logTreeFront(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();//用一个栈来存放树中的节点

    while (root != null || !stack.isEmpty()) {
           访问完毕)或者栈中还有节点(还有节点没有访问)
        while (root != null) {//一直往左走
            stack.push(root);//根节点入栈
            System.out.println(root.val);//前序点
            root = root.left;//访问左子树
        }
        root = stack.pop();//取出根节点
        root = root.right;//访问右子树
    }
}

3.中序遍历:非递归

public void logTreeCenter(TreeNode root){
    Stack<TreeNode> stack = new Stack<>();
    while(root != null || !stack.isEmpty()){//只要当前节点不为空(即当前节点的左右子树没有访                问完毕)或者栈中还有节点(还有节点没有访问)
        while(root != null){
            stack.push(root);//根节点入栈
            root = root.left;//访问左子树
        }
        root = stack.pop();//取出左子树的根节点
        System.out.println(root.val);//输出中序
        root = root.right;//访问右子树
    }
}

4.后序遍历:非递归

private void endLogTree(TreeNode tree) {
    if (tree == null)
        return;
    Stack<TreeNode> stack = new Stack<TreeNode>();
    TreeNode node = tree;
    TreeNode prev = null;
    while (node!=null||!stack.isEmpty()) {
        //处理左子树
        while (node != null) {
            stack.push(node);
            //这边继续遍历
            node = node.left;
        }

        node = stack.peek();
        //处理右子树
        if (node.right == null || node.right == prev) {
            //将顶部的出栈
            stack.pop();
            //打印节点
            System.out.println(node.val);
            prev = node;//下一个节点指向
            node = null;//当前节点遍历完,需要释放

        } else {
            node = node.right;
        }

    }
}

第四题:创建二叉树,完整树

public TreeNode createTree(int[] objs) {
    List<TreeNode> datas = new ArrayList<TreeNode>();
    for (Integer object : objs) {
        datas.add(new TreeNode(object));
    }
    TreeNode root = datas.get(0);//将第一个作为根节点
    for (int i = 0; i < objs.length / 2; i++) {
        //树是对称图像,只需要计算左边
        //左子树的位置2*1+1
        datas.get(i).left = datas.get(i * 2 + 1);
        //右子树:i*2+2
        if (i * 2 + 2 < datas.size()) {
            datas.get(i).right = datas.get(i * 2 + 2);
        }
    }

    return root;
}

第五题:二叉树的层遍历

public void logLevel(TreeNode treeNode) {
    if (treeNode == null)
        return;

    Queue<TreeNode> queue = new LinkedList<>();//层序遍历时保存结点的队列
    queue.offer(treeNode);//初始化
    while(!queue.isEmpty()){
        TreeNode node = queue.poll();
        System.out.print(node.val + " ");//访问节点
        if(node.left != null)
            queue.offer(node.left);
        if(node.right != null)
            queue.offer(node.right);
    }
}

备注:关于Queue的add和offer,一个会引起异常,一个不会。所以不了解队列的,可以自己看下API。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值