Java刷题-tree

一、分别按照二叉树先序,中序和后序打印所有的节点。

这道题就是书上的算法思想的实际使用,唯一需要特别注意到的是用递归的方式建树,还是比较巧妙的,因为一棵树的建立过程字符流是重复使用的,用递归的方式对根进行循环赋值。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Tree1 {
    //建立一棵树
    public static class Node {
        public int value;
        public Node left;
        public Node right;

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

    }

    //前序遍历
    public static void preOrderRecur(Node head) {
        if (head == null) {
            return;
        }
        System.out.print(head.value + " ");
        preOrderRecur(head.left);
        preOrderRecur(head.right);


    }

    //中序遍历
    public static void inOrderRecur(Node head) {
        if (head == null) {
            return;
        }
        inOrderRecur(head.left);
        System.out.print(head.value + " ");
        inOrderRecur(head.right);
    }

    //后续遍历
    public static void posOrderRecur(Node head) {
        if (head == null) {
            return;
        }
        posOrderRecur(head.left);
        posOrderRecur(head.right);
        System.out.print(head.value + " ");
    }

    public static Node treeGenerate(BufferedReader in) throws IOException {
        String[] str = in.readLine().split(" ");
        Node root = new Node(Integer.parseInt(str[0]));
        //递归进行赋值
        if (Integer.parseInt(str[1]) != 0) {
            //左孩子,递归调用再读一行root即为左孩子
            root.left = treeGenerate(in);
        }
        if (Integer.parseInt(str[2]) != 0) {
            //右孩子,递归调用再读一行root即为左孩子
            root.right = treeGenerate(in);
        }
        return root;

    }

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String[] str1 = bf.readLine().split(" ");
        Node root = treeGenerate(bf);
        preOrderRecur(root);
        System.out.println();
        inOrderRecur(root);
        System.out.println();
        posOrderRecur(root);
    }

}

二、二叉树的序列化

假设序列化的结果字符串为 str,初始时 str = "",遍历二叉树时,遇到 null 节点,则在 str 的末尾加上 "#!",否则加上"当前的节点值!"。

输出两行分别表示该二叉树的先序序列化和层序序列化

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    //建立一棵树
    public static class Node {
        public int value;
        public Node left;
        public Node right;

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

    //先序遍历
    public static StringBuilder preOrderRecur(Node head, StringBuilder sb) {
        if (head == null) {
            return sb.append("#!");
        }
        sb.append(head.value + "!");
        preOrderRecur(head.left, sb);
        preOrderRecur(head.right, sb);
        return sb;
    }


    //层序遍历
    public static StringBuilder layerOrder(Node head, StringBuilder sb) {
        if (head == null) {
            sb.append("#!");
        }
        Queue<Node> queue = new LinkedList<>();
        queue.add(head);
        sb.append(head.value).append("!");
        while (!queue.isEmpty()) {
            head = queue.poll();
            if (head.left != null) {
                sb.append(head.left.value).append("!");
                queue.add(head.left);
            } else {
                sb.append("#!");
            }
            if (head.right != null) {
                sb.append(head.right.value).append("!");
                queue.add(head.right);
            } else {
                sb.append("#!");
            }
        }
        return sb;
    }

    public static Node treeGenerate(BufferedReader in) throws IOException {
        String[] str = in.readLine().split(" ");
        Node root = new Node(Integer.parseInt(str[0]));
        //递归进行赋值
        if (Integer.parseInt(str[1]) != 0) {
            //左孩子,递归再调用
            root.left = treeGenerate(in);
        }
        if (Integer.parseInt(str[2]) != 0) {
            //右孩子,递归再调用
            root.right = treeGenerate(in);
        }
        return root;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String[] str1 = bf.readLine().split(" ");
        Node root = treeGenerate(bf);
        StringBuilder res1 = new StringBuilder();
        res1=preOrderRecur(root,res1);
        System.out.println(res1);
        StringBuilder res2 = new StringBuilder();
        res2 = layerOrder(root,res2);
        System.out.println(res2);
    }

}

这题目用String就是超时,必须要用StringBuilder。注意一下层序遍历是通过一个queue来存储的

感觉需要补充一下jvm的知识了。

三、二叉树的遍历在二叉树中找到累计和为制定值得最长路径

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

public class Main {
    //建立树的节点
    public static class Node {
        public int value;
        public Node left;
        public Node right;

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

    }

    //获取指定值的最长路径长度
    public static int getMaxLength(Node head, int sum) {
        //存储当前节点的最长路径值和所在的层数
        HashMap<Integer, Integer> sumMap = new HashMap<Integer, Integer>();
        sumMap.put(0, 0);   //没有遍历节点
        return preOrder(head, sum, 0, 1, 0, sumMap);
    }

    //
    public static int preOrder(Node head, int sum, int preSum, int level, int maxLen, HashMap<Integer, Integer> sumMap) {
        if (head == null) {
            return maxLen;  //记录其中的最大值
        }
        //当前节点的最大值计算
        int curSum = preSum + head.value;
        //集合中不存在当前值
        if (!sumMap.containsKey(curSum)) {
            sumMap.put(curSum, level);
        }
        //更新最大长度
        if (sumMap.containsKey(curSum - sum)) {
            //取两者的最大值
            maxLen = Math.max(level - sumMap.get(curSum - sum), maxLen);
        }
        //递归调用
        maxLen = preOrder(head.left, sum, curSum, level + 1, maxLen, sumMap);//左子树
        maxLen = preOrder(head.right, sum, curSum, level + 1, maxLen, sumMap);//右子树
        if (level == sumMap.get(curSum)) {
            sumMap.remove(curSum);
        }
        return maxLen;
    }

    public static Node buildTree(BufferedReader bufr) throws IOException {
        int left, right, data;
        String[] datas = bufr.readLine().split(" ");
        data = Integer.valueOf(datas[3]);
        right = Integer.valueOf(datas[2]);
        left = Integer.valueOf(datas[1]);
        Node head = new Node(data);
        if (left != 0) {
            head.left = buildTree(bufr);
        }
        if (right != 0) {
            head.right = buildTree(bufr);
        }
        return head;
    }


    public static void main(String[] args) throws Exception {
        //采用输入流接收输入
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        //将第一次换行符前的所以输入以空格分开并保存成字符串的形式,根据题意这里保不保存都无所谓的,反正递归创建没有用的
        String[] temp = bf.readLine().split(" ");
        int nodeNum = Integer.parseInt(temp[0]);//节点数目
        int firstNumber = Integer.parseInt(temp[1]); //第一个节点
        //创建树,这句和下面的sum位置交换后就会报错,不知道为什么
        Node root = buildTree(bf);
        int sum = Integer.parseInt(bf.readLine());
        //作为结果的输出流
        StringBuilder sb = new StringBuilder();
        System.out.println(getMaxLength(root, sum));
        //printTree(root);

    }

}

四、找到二叉树中的最大搜索二叉子树

本题非常的重要,有一个动态规划的固定套路

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
 
public class Main {
    public static class Node {
        public int value;
        public Node left;
        public Node right;
 
        public Node(int value) {
            this.value = value;
        }
    }
 
    public static class ReturnData {
        public int min;
        public int max;
        public Node head;
        public int size;
 
        public ReturnData(int min, int max, Node head, int size) {
            this.min = min;
            this.max = max;
            this.head = head;
            this.size = size;
        }
    }
 
    public static ReturnData process(Node head) {
        if (head == null) {
            return new ReturnData(Integer.MAX_VALUE, Integer.MIN_VALUE, null, 0);
        }
        Node left = head.left;
        ReturnData leftData = process(left);
        Node right = head.right;
        ReturnData rightData = process(right);
        int includeItself = 0;
        if (leftData.head == left && rightData.head == right
                && leftData.max < head.value
                && rightData.min > head.value) {
            includeItself = leftData.size + 1 + rightData.size;
        }
        int maxSize = Math.max(Math.max(leftData.size, rightData.size), includeItself);
        Node newHead = leftData.size > rightData.size ? leftData.head : rightData.head;
        if (maxSize == includeItself) {
            newHead = head;
        }
        return new ReturnData(Math.min(Math.min(leftData.min, rightData.min), head.value),
                Math.max(Math.max(leftData.max, rightData.max), head.value), newHead, maxSize);
    }
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        br.readLine();
        Node root = buildTree(br);
        System.out.println(process(root).size);
    }
 
    public static Node buildTree(BufferedReader br) throws IOException {
        String[] str = br.readLine().split(" ");
        int[] nodes = new int[str.length];
        for (int i = 0; i < nodes.length; i++) {
            nodes[i] = Integer.parseInt(str[i]);
        }
        Node root = new Node(nodes[0]);
        if (nodes[1] != 0) {
            root.left = buildTree(br);
        }
        if (nodes[2] != 0) {
            root.right = buildTree(br);
        }
        return root;
    }
}

五、找到二叉树中符合搜索二叉树条件的最大拓扑结构

递归使用很重要,这个解法用了很多递归很值得学习

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Tree5 {
    //建立一棵树
    public static class Node {
        int value;
        Node left;
        Node right;

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

    public static int bstTopoSize1(Node head) {
        //寻找所有节点的最大拓扑结构
        if (head == null) {
            return 0;
        }
        int max = maxTopo(head, head);
        max = Math.max(bstTopoSize1(head.left), max);
        max = Math.max(bstTopoSize1(head.right), max);
        return max;
    }

    public static int maxTopo(Node h, Node n) {
        //搜索以h为头节点的最大拓扑结构
        if (h != null && n != null && isBSTNode(h, n, n.value)) {
            //以h为头节点的满足要求,继续从左右子树开始搜索
            return maxTopo(h, n.left) + maxTopo(h, n.right) + 1;
        }
        return 0;
    }

    public static boolean isBSTNode(Node h, Node n, int value) {
        //判断n节点是否在以h节点为头节点的搜索二叉树上
        if (h == null) {
            return false;
        }
        if (h == n) {
            return true;
        }
        return isBSTNode(h.value > value ? h.left : h.right, n, value);
    }

    public static Node treeGenerate(BufferedReader in) throws IOException {
        String[] str = in.readLine().split(" ");
        Node root = new Node(Integer.parseInt(str[0]));
        //递归进行赋值
        if (Integer.parseInt(str[1]) != 0) {
            //左孩子,递归再调用
            root.left = treeGenerate(in);
        }
        if (Integer.parseInt(str[2]) != 0) {
            //右孩子,递归再调用
            root.right = treeGenerate(in);
        }
        return root;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        bf.readLine();
        Node root=treeGenerate(bf);
        System.out.println(bstTopoSize1(root));
    }


}

六、二叉树的按层打印与ZigZag打印

给定一颗二叉树,分别实现按层和 ZigZag 打印二叉树。

ZigZag遍历: 意思是第一层从左到右遍历,第二层从右到左遍历,依次类推。

有个更好的办法就是读取一层,然后计算queue的长度,并且再将左子树右子树压入队列中

public static void printByLevel3(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        int level = 1;

        queue.offer(root);
        System.out.print("Level " + level++ + ":");
        while (!queue.isEmpty()) {
            int length = queue.size();  // - 核心点  区分:标识当前层和下一层的分界位置
            //换行时刻
            for (int i = 0; i < length; i++) {
                TreeNode curr = queue.poll();
                if (curr.left != null) {
                    queue.offer(curr.left);
                }
                if (curr.right != null) {
                    queue.offer(curr.right);
                }
                System.out.print(curr.value + " ");
            }

            //注:其中!queue.isEmpty()判断可忽略,这里只是为了打印好看,才加的判断
            if (!queue.isEmpty()) {
                System.out.print("\nLevel " + level++ + " : ");
            }

        }
    }

书上的方法用的是俩个标志位last和nLast,也是很好的方法,难以理解一点。

之字打印目前比较好理解的就是用俩stack,存数据,再出来打印

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;

//二叉树的按层打印与zigzag打印
public class Tree6 {
    public static class Node {
        int value;
        Node left;
        Node right;

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

    public static void printByLevel(Node head) {
        if (head == null) return;
        Queue<Node> queue = new LinkedList<>();
        int level = 1;
        Node last = head;
        Node nLast = null;
        queue.add(head);
        System.out.print("Level " + (level++) + " : ");
        while (!queue.isEmpty()) {
            head = queue.poll();
            System.out.print(head.value + " ");
            if (head.left != null) {
                queue.add(head.left);
                nLast = head.left;
            }
            if (head.right != null) {
                queue.add(head.right);
                nLast = head.right;
            }
            if(head==last&&!queue.isEmpty()){
                System.out.print("\nLevel "+(level++)+" : ");
                last=nLast;
            }
        }
        System.out.println();
    }

    public static Node treeGenerate(BufferedReader in) throws IOException {
        String[] str = in.readLine().split(" ");
        Node root = new Node(Integer.parseInt(str[0]));
        //递归进行赋值
        if (Integer.parseInt(str[1]) != 0) {
            //左孩子,递归再调用
            root.left = treeGenerate(in);
        }
        if (Integer.parseInt(str[2]) != 0) {
            //右孩子,递归再调用
            root.right = treeGenerate(in);
        }
        return root;
    }


    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        bf.readLine();
        Node root = treeGenerate(bf);
        printByLevel(root);
    }



}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        br.readLine();
        TreeNode root = createTree(br);
        layerPrint(root);
        zigZag(root);
    }
    public static void zigZag(TreeNode root){
        if(root==null) return;
        Stack<TreeNode> s1 = new Stack<>();
        Stack<TreeNode> s2 = new Stack<>();
        s1.add(root);
        int level = 1;
        TreeNode node;
        StringBuilder sb;
        while(!s1.isEmpty()||!s2.isEmpty()){
            if(!s1.isEmpty()){
                sb = new StringBuilder();
                sb.append("Level "+level+" from left to right: ");
                while(!s1.isEmpty()){
                    node = s1.pop();
                    sb.append(node.val+" ");
                    if(node.left!=null){
                        s2.add(node.left);
                    }
                    if(node.right!=null){
                        s2.add(node.right);
                    }
                }
                level++;
                System.out.println(sb.toString().trim());
            }
            if(!s2.isEmpty()){
                sb = new StringBuilder();
                sb.append("Level "+level+" from right to left: ");
                while(!s2.isEmpty()){
                    node = s2.pop();
                    sb.append(node.val+" ");
                    if(node.right!=null){
                        s1.add(node.right);
                    }
                    if(node.left!=null){
                        s1.add(node.left);
                    }
                }
                level++;
                System.out.println(sb.toString().trim());
            }           
        }
    }
    public static void layerPrint(TreeNode root){
        if(root==null) return;
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        int presize = 1;
        int size = 0;
        int count = 1;
        while(!q.isEmpty()){
            StringBuilder sb = new StringBuilder();
            sb.append("Level "+count+" : ");
            while((presize--)>0){
                TreeNode node = q.poll();
                sb.append(node.val+" ");
                if(node.left!=null){
                    size++;
                    q.add(node.left);
                }
                if(node.right!=null){
                    size++;
                    q.add(node.right);
                }
            }
            presize = size;
            size = 0;
            count++;
            System.out.println(sb.toString().trim());
        }
    }
    //递归建树
    public static TreeNode createTree(BufferedReader br){
        try{
            String[] ss = br.readLine().trim().split(" ");
            int data = Integer.parseInt(ss[0]);
            int left = Integer.parseInt(ss[1]);
            int right = Integer.parseInt(ss[2]);
            TreeNode root = new TreeNode(data);
            if(left!=0){
                root.left = createTree(br);
            }
            if(right!=0){
                root.right = createTree(br);
            }
            return root;
        }catch(Exception e){
            return null;
        }
    }
 
 
}
class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    public TreeNode(int val){
        this.val = val;
    }
}

七、按升序输出二叉树的两个错误节点的值。(每个节点的值各不相同)

这个题目要点是考虑到是二叉搜索树,所以应该是按中序进行遍历, 从小到大的顺序进行输出,第一个错误点是出现前者大于后者的前者节点,第二个错误是前者大于后者的后者节点。

注意看看左神改写的中序遍历真的很厉害。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class Tree7 {
    public static class Node {
        //建立一棵树
        public int value;
        public Node left;
        public Node right;

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

    public static Node[] getTwoErNodes(Node head) {
        Node[] errs = new Node[2];
        if (head == null) return errs;
        Stack<Node> stack = new Stack<>();
        Node pre = null;
        while (!stack.isEmpty() || head != null) {
            if (head != null) {
                stack.push(head);
                head = head.left;
            } else {
                head = stack.pop();
                if (pre != null && pre.value > head.value) {
                    errs[0] = errs[0] == null ? pre : errs[0];
                    errs[1] = head;
                }
                pre = head;
                head = head.right;
            }
        }
        return errs;

    }

    public static Node treeGenerate(BufferedReader in) throws IOException {
        String[] str = in.readLine().split(" ");
        Node root = new Node(Integer.parseInt(str[0]));
        //递归进行赋值
        if (Integer.parseInt(str[1]) != 0) {
            //左孩子,递归调用再读一行root即为左孩子
            root.left = treeGenerate(in);
        }
        if (Integer.parseInt(str[2]) != 0) {
            //右孩子,递归调用再读一行root即为左孩子
            root.right = treeGenerate(in);
        }
        return root;

    }

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String[] str1 = bf.readLine().split(" ");
        Node root = treeGenerate(bf);
        Node[] errs=getTwoErNodes(root);
        if(errs[0].value>errs[1].value) System.out.println(errs[1].value+" "+errs[0].value);
        else System.out.println(errs[0].value+" "+errs[1].value);
    }


}

八、判断t1树是否右与t2树拓扑结构相同的子树

这个递归用的太好了,哎要多学习

public class Tree8 {
    public static class Node {
        public int value;
        public Node left;
        public Node right;

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

    public static boolean contains(Node t1, Node t2) {
        if (t2 == null) {
            return true;
        }
        if (t1 == null) {
            return false;
        }
        return check(t1, t2) || contains(t1.left, t2) || contains(t1.right, t2);
    }

    public static boolean check(Node h, Node t2) {
        if (t2 == null) {
            return true;
        }
        if (h == null || h.value != t2.value) {
            return false;
        }
        return check(h.left, t2.left) && check(h.right, t2.right);
    }
}

九、判断二叉树是否为平衡二叉树

public class Tree9 {
    public static class Node {
        public int value;
        public Node left;
        public Node right;

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

    public static class ReturnType {
        public boolean isBalanced;
        public int height;

        public ReturnType(boolean isBalanced, int height) {
            this.isBalanced = isBalanced;
            this.height = height;
        }
    }

    public static ReturnType process(Node head) {
        if (head == null) {
            return new ReturnType(true, 0);
        }
        ReturnType leftData = process(head.left);
        ReturnType rightData = process(head.right);
        int height = Math.max(leftData.height, rightData.height) + 1;
        boolean isBalanced = leftData.isBalanced && rightData.isBalanced && Math.abs(leftData.height - rightData.height) < 2;
        return new ReturnType(isBalanced, height);
    }

    public static boolean isBalanced(Node head) {
        return process(head).isBalanced;
    }


}

十、根据后序数组重建搜索二叉树

less和more的关系很重要,两者相差了一位。

public class Tree10 {
    public static class Node {
        Node left;
        Node right;
        int value;

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

    public static boolean isPostArray(int[] arr) {
        if (arr == null || arr.length == 0) {
            return false;
        }
        return isPost(arr, 0, arr.length - 1);
    }

    public static boolean isPost(int[] arr, int start, int end) {
        //more记录搜索二叉树的右子树的第一个值
        //less记录搜索二叉树的左子树的最后一个值
            if (start == end) {
            return true;
        }
        int less = -1;
        int more = end;
        for (int i = start; i < end; i++) {
            if (arr[end] > arr[i]) {
                less = i;
            } else {
                more = more == end ? i : more;
            }
        }
        if (less == -1 || more == end) {
            return isPost(arr, start, end - 1);
        }
        if (less != more - 1) {
            return false;
        }
        return isPost(arr, start, less) && isPost(arr, more, end - 1);
    }

}

十一、判断一棵二叉树是否为搜索二叉树和完全二叉树

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class Tree11 {
    public static class Node {
        Node left;
        Node right;
        int value;

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

    public static ArrayList<Integer> arrayList = new ArrayList<>();

    //中序遍历的搜索二叉树必定为单调递增序列
    public static void inOrderRecur(Node head) {
        if (head == null) return;
        inOrderRecur(head.left);
        arrayList.add(head.value);
        inOrderRecur(head.right);
    }

    public static boolean layerOrder(Node head) {
        int flag = 0;
        if (head == null) return true;
        Queue<Node> queue = new LinkedList<>();
        queue.add(head);
        while (!queue.isEmpty()) {
            head = queue.poll();
            if (head.left == null && head.right != null) return false;
            if (head.left != null && head.right != null) {
                queue.add(head.left);
                queue.add(head.right);
            }
            if (flag == 1 && (head.left != null || head.right != null)) return false;
            if (head.left == null && head.right == null) {
                flag = 1;
            }

        }
        return true;
    }

    public static Node treeGenerate(BufferedReader in) throws IOException {
        String[] str = in.readLine().split(" ");
        Node root = new Node(Integer.parseInt(str[0]));
        //递归进行赋值
        if (Integer.parseInt(str[1]) != 0) {
            //左孩子,递归调用再读一行root即为左孩子
            root.left = treeGenerate(in);
        }
        if (Integer.parseInt(str[2]) != 0) {
            //右孩子,递归调用再读一行root即为左孩子
            root.right = treeGenerate(in);
        }
        return root;

    }

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        bf.readLine();
        Node root = treeGenerate(bf);
        //搜索二叉树判断
        inOrderRecur(root);
        boolean flag = true;
        for (int i = 0; i + 1 < arrayList.size(); i++) {
            if (arrayList.get(i) > arrayList.get(i + 1)) flag = false;
        }
        System.out.println(flag);
        System.out.println(layerOrder(root));
    }
}

十二、在一棵二叉树中找后继节点,也就是中序的下一个节点

这个题目的输入有问题坑哭了,就是中序然后遍历找后面一个节点。

做题半小时。调试1小时,最后发现给的数据错了,球球牛客网长点心吧。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class Tree12 {
    public static class Node {
        Node left;
        Node right;
        int value;

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

    public static ArrayList<Integer> arrayList = new ArrayList<>();

    public static void mid_order(Node head) {
        if (head == null) return;
        mid_order(head.left);
        arrayList.add(head.value);
        mid_order(head.right);
    }

    public static Node treeGenerate(BufferedReader in) throws IOException {
        String[] str = in.readLine().split(" ");
        Node root = new Node(Integer.parseInt(str[0]));
        //递归进行赋值
        if (Integer.parseInt(str[1]) != 0) {
            //左孩子,递归调用再读一行root即为左孩子
            root.left = treeGenerate(in);
        }
        if (Integer.parseInt(str[2]) != 0) {
            //右孩子,递归调用再读一行root即为左孩子
            root.right = treeGenerate(in);
        }
        return root;

    }

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        bf.readLine();
        Node root = treeGenerate(bf);
        mid_order(root);
        String str = bf.readLine();
        int value=Integer.parseInt(str);
//        System.out.println(value);
//        System.out.println(arrayList);
        if(value==arrayList.get(arrayList.size()-1)) System.out.println(0);
        for (int i = 0; i < arrayList.size()-1; i++) {
            if(arrayList.get(i)==value) System.out.println(arrayList.get(i+1));
        }
    }


}

十三、在二叉树中找到俩个节点的最近公共祖先

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static class Node {
        Node left;
        Node right;
        int value;

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

    public static Node lowestAncestor(Node head, Node o1, Node o2) {
        if (head == null || head.value == o1.value || head.value == o2.value) {
            return head;
        }
        Node left = lowestAncestor(head.left, o1, o2);
        Node right = lowestAncestor(head.right, o1, o2);
        if (left != null && right != null) {
            return head;
        }
        //left和right一个为空一个不为空则直接返回不为空的那个
        return left != null ? left : right;

    }

    public static Node treeGenerate(BufferedReader in) throws IOException {
        String[] str = in.readLine().split(" ");
        Node root = new Node(Integer.parseInt(str[0]));
        //递归进行赋值
        if (Integer.parseInt(str[1]) != 0) {
            //左孩子,递归调用再读一行root即为左孩子
            root.left = treeGenerate(in);
        }
        if (Integer.parseInt(str[2]) != 0) {
            //右孩子,递归调用再读一行root即为左孩子
            root.right = treeGenerate(in);
        }
        return root;

    }

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        bf.readLine();
        Node root = treeGenerate(bf);
        String[] str = bf.readLine().split(" ");
        Node o1 = new Node(Integer.parseInt(str[0]));
        Node o2 = new Node(Integer.parseInt(str[1]));
        Node result=lowestAncestor(root,o1,o2);
        System.out.println(result.value);
    }


}

十四、二叉树节点间的最大距离问题 

用动态规划的思想来做,需要注意的是重视过程不重视结果

考虑俩个事情:

1、递归的条件 、递归条件

2、递归边界

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
 
public class Main {
    private static class Node {
        public int value;
        public Node left;
        public Node right;
         
        public Node(int value) {
            this.value = value;
        }
    }
     
    private static class ReturnType {
        /**
         * 以该节点为头节点的二叉树节点间的最大距离
         */
        public int maxLength;
         
        /**
         * 以该节点为头节点的二叉树的高度
         */
        public int height;
         
        public ReturnType(int maxLength, int height) {
            this.maxLength = maxLength;
            this.height = height;
        }
    }
     
    private static int getMaxLength(Node head) {
        if (head == null) {
            return 0;
        }
        return process(head).maxLength;
    }
     
    private static ReturnType process(Node head) {
        if (head == null) {
            return new ReturnType(0, 0);
        }
         
        // 得到左子树与右子树的返回信息
        ReturnType leftInfo = process(head.left);
        ReturnType rightInfo = process(head.right);
         
        // 最大距离为左子树中最大距离、右子树中最大距离、左子树高度+右子树高度+1 这三者中的最大值
        int maxLength = Math.max(leftInfo.maxLength, rightInfo.maxLength);
        maxLength = Math.max(leftInfo.height + rightInfo.height + 1, maxLength);
         
        int height = Math.max(leftInfo.height, rightInfo.height) + 1;
        return new ReturnType(maxLength, height);
    }
 
    private static Node createTree(BufferedReader reader) {
        try {
            String[] strs = reader.readLine().split(" ");
            int[] arr = new int[strs.length];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = Integer.valueOf(strs[i]);
            }
             
            Node head = new Node(arr[0]);
            head.left = arr[1] == 0 ? null : createTree(reader);
            head.right = arr[2] == 0 ? null : createTree(reader);
             
            return head;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
     
    public static void main(String[] args) {
        Node head = null;
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
            reader.readLine();
            head = createTree(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }
         
        System.out.println(getMaxLength(head));
    }
}

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值