java求一颗二叉树从根到叶子节点之和的最大值及二叉树的遍历

2 篇文章 0 订阅
1 篇文章 0 订阅

求一颗二叉树从根到叶子节点之和的最大值

比如:
1
2 3
4 1 6
分支分别是:
1+2+4=7
1+2+1=4
1+3+6=10
所以最大值是10

大体思路

将根到叶子节点所有路径的值求出来,然后分别计算每条路径的和进行比较,得出最大值,

  • 第一步: 求出根到叶子节点路径的集合
public static void findPath(Node node, List<List<Node>> paths, List<Node> tempPath) {
        //将当前节点放入到临时路径中
        tempPath.add(node);

        //当前节点没有左右节点时,为叶子节点,也就是从根节点到叶子节点的一条路径
        if (node.getLeft() == null && node.getRight() == null) {
            List<Node> list = new ArrayList<>();
            list.addAll(tempPath);//将确定的这条路径放入到一个list中,不能直接将tempPath放入到paths中,因为后续要对tempPath进行操作
            paths.add(list);//将路径保存到路径集合中
            tempPath.remove(node);//处理完一条路径之后,将这个叶子节点删除,方便后续继续处理
        }

        if (node.getLeft() != null) {
            findPath(node.getLeft(), paths, tempPath);
        }

        if (node.getRight() != null) {
            if (node.getLeft() != null) {//遍历到右子树的时候,需要将之前保存的左子树节点删除,可能当前临时路径中没有左子树节点,也可能有
                int index = tempPath.indexOf(node);//找到当前节点父节点的位置,
                tempPath = tempPath.subList(0, index + 1);//从根节点截取到当前父节点的位置(包括当前父节点),做为新的临时路径
            }
            findPath(node.getRight(), paths, tempPath);
        }
    }
  • 第二步: 计算每条路径和,进行比较返回最大
public static int cascSum(Node root){
        List<Node> tempPath = new ArrayList<Node>();
        List<List<Node>> paths = new ArrayList<List<Node>>();
        findPath(root, paths, tempPath);

        int sum = 0;
        for (int i = 0; i < paths.size(); i++){
            List<Node> path = paths.get(i);
            int tempSum = 0;
            for(Node node : path){
                tempSum += node.getValue();
            }
            if (sum < tempSum){
                sum = tempSum;
            }
        }
        return sum;
    }

测试及遍历二叉树

对于数据结构和算法真的不熟,也是自己的短板,后续逐步加强.
下面代码是二叉树的遍历和上边问题的测试,都有了,参考了网上的一些文章和数据结构的教材

package com.fat;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * @ClassName Node
 * @Auther LangGuofeng
 * @Date: 2019/9/26/026 21:12
 * @Description: 求一颗二叉树从根到叶子节点之和的最大值
 * 比如:
 * 1
 * 2 3
 * 4 1 6
 * 分支分别是:
 * 1+2+4=7
 * 1+2+1=4
 * 1+3+6=10
 * 所以最大值是10
 */
public class Node {

    int value;
    Node left;
    Node right;

    public int getValue() {
        return value;
    }

    public Node getLeft() {
        return left;
    }

    public Node getRight() {
        return right;
    }

    public Node(int value) {
        this.value = value;
    }

    int calcSum(Node root) {
        int max = 0;
        return 0;
    }

    //先序遍历
    public static void preOrder(Node root) {
        if (root == null)
            return;
        System.out.println(root.getValue());
        preOrder(root.getLeft());
        preOrder(root.getRight());
    }

    //中序遍历
    public static void inOrder(Node root){
        if(root == null)
            return;
        inOrder(root.getLeft());
        System.out.println(root.getValue());
        inOrder(root.getRight());
    }

    //后序遍历
    public static void postOrder(Node root) {
        if (root == null)
            return;
        postOrder(root.getLeft());
        postOrder(root.getRight());

        System.out.println(root.getValue());
    }

    //非递归
    //先序遍历
    public static void iteratorPre(Node root){
        Stack<Node> stack = new Stack<Node>();
        stack.push(root);
        //每次取出节点的顺序总是根,左,右
        while(!stack.isEmpty()){
            root = stack.pop();
            System.out.println(root.getValue());
            //先压入右节点,再压入左节点,因为栈是先进后出的
            if(root.getRight() != null)
                stack.push(root.getRight());
            if(root.getLeft() != null)
                stack.push(root.getLeft());
        }
    }

    //先序遍历2
    protected static void iterativePreorder2(Node root) {
        Stack<Node> stack = new Stack<Node>();
        Node node = root;
        while (node != null || stack.size() > 0) {
            while (node != null) {//压入所有的左节点,压入前访问它
                System.out.println(node.value);
                stack.push(node);
                node = node.getLeft();
            }
            if (stack.size() > 0) {
                node = stack.pop();
                node = node.getRight();
            }
        }
    }

    //中序遍历
    protected static void iterativeInorder(Node root) {
        Stack<Node> stack = new Stack<Node>();
        Node node = root;
        while (node != null || stack.size() > 0) {
            //压入根节点和左节点
            while (node != null) {
                stack.push(node);
                node = node.getLeft();
            }
            if (stack.size() > 0) {
                node = stack.pop();
                System.out.println(node.value);
                node = node.getRight();
            }
        }
    }

    //后序遍历,单栈
    protected static void iterativePostorder3(Node root) {
        Stack<Node> stack = new Stack<Node>();
        Node node = root, prev = root;
        while (node != null || stack.size() > 0) {
            while (node != null) {
                stack.push(node);
                node = node.getLeft();
            }
            if (stack.size() > 0) {
                Node temp = stack.peek().getRight();
                if (temp == null || temp == prev) {
                    node = stack.pop();
                    System.out.println(node.value);
                    prev = node;
                    node = null;
                } else {
                    node = temp;
                }
            }
        }
    }

    public static void main(String[] args) {
        Node root = new Node(1);
        Node node1 = new Node(2);
        Node node2 = new Node(3);
        Node node3 = new Node(4);
        Node node4 = new Node(1);
        Node node5 = new Node(6);
        root.left = node1;
        root.right = node2;
        node1.left = node3;
        node1.right = node4;
        node2.right = node5;
//        Node node6 = new Node(8);
//        Node node7 = new Node(12);
//        node5.right = node6;
//        node5.left = node7;

        System.out.println(cascSum(root));

//        findPath(root);
//        for (List<Node> item : mRoutes) {
//            System.out.println("........." + getNodePath(item));
//        }


//        preOrder(root);

//        Stack<Node> n = new Stack<Node>();
//         ArrayList<Integer> list = findMin(root,n);
//        //list中是各条路径的和
//        for(int i = 0;i < list.size();i++){
//            System.out.println(list.get(i));
//        }


//        System.out.println("----------------------------");
//        preOrder(root);
//        System.out.println("----------------------------");
//        inOrder(root);
//        System.out.println("----------------------------");
//        postOrder(root);
//        System.out.println("----------------------------");
//        iteratorPre(root);
//        System.out.println("----------------------------");
//        iterativePreorder2(root);
//        System.out.println("----------------------------");
//        iterativeInorder(root);
//        System.out.println("----------------------------");
//        iterativePostorder3(root);
    }

    public static int cascSum(Node root){
        List<Node> tempPath = new ArrayList<Node>();
        List<List<Node>> paths = new ArrayList<List<Node>>();
        findPath(root, paths, tempPath);

        int sum = 0;
        for (int i = 0; i < paths.size(); i++){
            List<Node> path = paths.get(i);
            int tempSum = 0;
            for(Node node : path){
                tempSum += node.getValue();
            }
            if (sum < tempSum){
                sum = tempSum;
            }
        }

        return sum;
    }

    public static void findPath(Node node, List<List<Node>> paths, List<Node> tempPath) {
        //将当前节点放入到临时路径中
        tempPath.add(node);

        //当前节点没有左右节点时,为叶子节点,也就是从根节点到叶子节点的一条路径
        if (node.getLeft() == null && node.getRight() == null) {
            List<Node> list = new ArrayList<>();
            list.addAll(tempPath);//将确定的这条路径放入到一个list中,不能直接将tempPath放入到paths中,因为后续要对tempPath进行操作
            paths.add(list);//将路径保存到路径集合中
            tempPath.remove(node);//处理完一条路径之后,将这个叶子节点删除,方便后续继续处理
        }

        if (node.getLeft() != null) {
            findPath(node.getLeft(), paths, tempPath);
        }

        if (node.getRight() != null) {
            if (node.getLeft() != null) {//遍历到右子树的时候,需要将之前保存的左子树节点删除,可能当前临时路径中没有左子树节点,也可能有
                int index = tempPath.indexOf(node);//找到当前节点父节点的位置,
                tempPath = tempPath.subList(0, index + 1);//从根节点截取到当前父节点的位置(包括当前父节点),做为新的临时路径
            }
            findPath(node.getRight(), paths, tempPath);
        }
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值