二叉树的识别与应用

前言

二叉树节点结构:

  public static class Node{
        public Node left;
        public Node right;
        public int value;
        public Node(int data){
            this.value=data;
        }
    }

代码中实现的二叉树都为图片所示二叉树

一、二叉树的先序、中序、后序遍历

在这里插入图片描述
二叉树递归序:1->2->3->3->3->2->4->4->4->2->1->6->7->7->7->6->1

先序:1->2->3->4->6->7
中序:3->2->4->1->7->6
后序:3->4->2->7->6->1

1、递归方式(先序、中序、后序)

public class traverse {
    public static void main(String[] args) {
        Node head=new Node(1);
        head.left=new Node(2);
        head.right=new Node(6);
        head.left.left=new Node(3);
        head.left.right=new Node(4);
        head.right.left=new Node(7);

        System.out.println("==============二叉树遍历===============");
        System.out.print("pree-order: ");
        preorderTraversal(head);

        System.out.println();
        System.out.print("in-order: ");
        inorderTraversal(head);

        System.out.println();
        System.out.print("pos-order: ");
        postOrderTraversal(head);

    }
    // 树节点
    public static class Node{
        public int value;
        public Node left;
        public Node right;

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

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

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

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

运行结果:
在这里插入图片描述

2、非递归(先序、中序、后序)

public static void main(String[] args) {
        traverse.Node head=new traverse.Node(1);
        head.left=new traverse.Node(2);
        head.right=new traverse.Node(6);
        head.left.left=new traverse.Node(3);
        head.left.right=new traverse.Node(4);
        head.right.left=new traverse.Node(7);

        System.out.println("==============二叉树非递归遍历===============");
        preOrderUnRecur(head);

        System.out.println();
        inOrderUnRecur(head);

        System.out.println();
        posOrderUnRecur1(head);


    }
    // 树节点
    public static class Node{
        public int value;
        public traverse.Node left;
        public traverse.Node right;

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

    //先序遍历
    public static void preOrderUnRecur(Node head){
        System.out.print("pre-order: ");
        if (head!=null){
            Stack<Node> stack=new Stack<Node>();
            stack.add(head);
            while (!stack.isEmpty()){
                head=stack.pop();
                System.out.print(head.value+" ");
                if (head.right!=null){
                    stack.push(head.right);
                }
                if (head.left!=null){
                    stack.push(head.left);
                }
            }
        }
        System.out.println();
    }

    //中序遍历
    public static void inOrderUnRecur(Node head){
        System.out.print("in-order: ");
        if (head!=null){
            Stack<Node>stack=new Stack<Node>();
            while (!stack.isEmpty() || head != null){
                if (head!=null){// 把左边界都入栈
                    stack.push(head);
                    head=head.left;
                }else {// 依次弹节点并跳到右结点
                    head=stack.pop();
                    System.out.print(head.value+" ");
                    head=head.right;
                }
            }
        }
        System.out.println();
    }

    // 后序遍历
    // 用先序遍历的 头右左 逆序输出就是后序遍历
    public static void posOrderUnRecur1(Node head){
        System.out.print("pos-order: ");
        if (head!=null){
            Stack<Node>s1=new Stack<Node>();
            Stack<Node>s2=new Stack<Node>();
            s1.push(head);
            while (!s1.isEmpty()){
                head=s1.pop();
                s2.push(head);
                if (head.left!=null){
                    s1.push(head.left);
                }
                if (head.right!=null){
                    s1.push(head.right);
                }
            }
            while (!s2.isEmpty()){
                System.out.print(s2.pop().value+" ");
            }
        }
        System.out.println();
    }

运行结果:
在这里插入图片描述

二、宽度优先遍历

1.遍历

public static void main(String[] args) {
        Node head=new Node(1);
        head.left=new Node(2);
        head.right=new Node(6);
        head.left.left=new Node(3);
        head.left.right=new Node(4);
        head.right.left=new Node(7);
        System.out.println("==========宽度优先遍历===========");
        w(head);
    }
    public static class Node{
        public int value;
        public Node left;
        public Node right;

        public Node(int data){
            this.value=data;
        }
    }
    public static void w(Node head){
        if (head==null){
            return;
        }
        Queue<Node>queue=new LinkedList<>();
        queue.add(head);
        while (!queue.isEmpty()){
            Node cur=queue.poll();
            System.out.print(cur.value+" ");
            if (cur.left!=null){
                queue.add(cur.left);
            }
            if (cur.right!=null){
                queue.add(cur.right);
            }
        }
    }

运行结果:
在这里插入图片描述

2、最大宽度查找

public static void main(String[] args) {
        Node head=new Node(1);
        head.left=new Node(2);
        head.right=new Node(6);
        head.left.left=new Node(3);
        head.left.right=new Node(4);
        head.right.left=new Node(7);

        System.out.println("==========最大宽度===========");
        System.out.println("该树最大宽度为: "+w(head));
    }
    public static class Node{
        public int value;
        public Node left;
        public Node right;

        public Node(int data){
            this.value=data;
        }
    }
    public static int w(Node head){
        if (head==null){
            return 0;
        }
        Queue<Node> queue=new LinkedList<>();
        queue.add(head);
        HashMap<Node,Integer>levelMap=new HashMap<>();
        levelMap.put(head,1);
        int curLevel=1;
        int curLevelNodes=0;
        int max=Integer.MIN_VALUE;
        while (!queue.isEmpty()){
           Node cur=queue.poll();
           int curNodeLevel=levelMap.get(cur);
           if (curNodeLevel==curLevel){
               curLevelNodes++;
           }else {
               max=Math.max(max,curLevelNodes);
               curLevel++;
               curLevelNodes=1;
           }
            if (cur.left!=null){
                levelMap.put(cur.left,curNodeLevel+1);
                queue.add(cur.left);
            }
            if (cur.right!=null){
                levelMap.put(cur.right,curNodeLevel+1);
                queue.add(cur.right);
            }
        }
        max=Math.max(max,curLevelNodes);
        return max;
    }

运行结果:
在这里插入图片描述

三、是否为搜索二叉树

1、搜索二叉树

整棵树右子树要大于左子树的值,称该树为搜索二叉树,如图:

在这里插入图片描述

2、判断搜索二叉树

利用中序遍历的特点(左中右),如果为是搜索二叉树,则中序遍历是逐渐增大的。

分为递归和非递归方式

public static void main(String[] args) {
        Node head=new Node(8);
        head.left=new Node(3);
        head.right=new Node(10);
        head.left.left=new Node(1);
        head.left.right=new Node(6);
        head.left.right.left=new Node(4);
        head.left.right.right=new Node(7);
        head.right.right=new Node(14);
        head.right.right.left=new Node(13);
        System.out.print("递归方式: ");
        System.out.println(checkBST(head)?"是一颗搜索二叉树":"不是一颗搜索二叉树");
        System.out.print("非递归方式: ");
        System.out.println(checkBST2(head)?"是一颗搜索二叉树":"不是一颗搜索二叉树");
    }

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

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

    public static int preValue=Integer.MIN_VALUE;

    //递归 判断是否为搜索二叉树
    public static Boolean checkBST(Node head){
        if (head==null){
            return true;
        }
        boolean isLeftBst=checkBST(head.left);
        if (!isLeftBst){
            return false;
        }
        if (head.value<=preValue){
            return false;
        }else {
            preValue= head.value;
        }
        return checkBST(head.right);
    }

    //非递归
    public static int preValue2=Integer.MIN_VALUE;
    public static Boolean checkBST2(Node head){
        if (head!=null){
            Stack<Node>stack=new Stack<Node>();
            while (!stack.isEmpty() || head != null){
                if (head!=null){// 把左边界都入栈
                    stack.push(head);
                    head=head.left;
                }else {// 依次弹节点并跳到右结点
                    head=stack.pop();
                    if (head.value<=preValue2){
                        return false;
                    }else {
                        preValue2= head.value;
                    }
                    head=head.right;
                }
            }
        }
       return true;
    }

运行结果:

在这里插入图片描述


套路递归:
每一颗子树都应该满足:左子树<父节点<右子树

构建信息体:

 public static class ReturnData{// 信息体
        public boolean isBST;
        public int min;
        public int max;

        public ReturnData(boolean is,int min,int max){
            this.isBST=is;
            this.min=min;
            this.max=max;
        }
    }

加工信息:

public static ReturnData process(Node x){
        if (x==null){
            return null;
        }
        ReturnData leftData=process(x.left);
        ReturnData rightData=process(x.right);
        int min=x.value;
        int max= x.value;
        if (leftData!=null){// 左子树中最大和最小
            min=Math.min(min, leftData.min);
            max=Math.max(max, leftData.max);
        }
        if (rightData!=null){// 右子树中最大和最小
            min=Math.min(min, rightData.min);
            max=Math.max(max, rightData.max);
        }

        boolean isBST=true;
        // 左子树不为空和(左子树>=父节点 或 左子树不为搜索二叉树)
        if (leftData!=null && (!leftData.isBST || leftData.max>=x.value)){
            isBST=false;
        }
        // 右子树不为空和(右子树<=父节点 或 右子树不为搜索二叉树)
        if (rightData!=null && (!rightData.isBST ||x.value>=rightData.min)){
            isBST=false;
        }
        return new ReturnData(isBST,min,max);//最终返回
    }

四、是否为完全二叉树

在这里插入图片描述

完全二叉树的两个条件

  1. 某个节点左孩子为空右孩子不能为空
  2. 在一的条件下遇到过左右两孩子不双全的节点,当前节点不能有叶子节点

代码如下

public static void main(String[] args) {
        Node head=new Node(1);
        head.left=new Node(2);
        head.right=new Node(3);
        head.left.left=new Node(4);
        head.left.right=new Node(5);
        head.right.left=new Node(6);
        head.right.right=new Node(7);
        head.left.left.left=new Node(8);
        head.left.left.right=new Node(9);
        head.left.right.left=new Node(10);
        head.left.right.right=new Node(11);
        head.right.left.left=new Node(12);
        System.out.println("是否为完全二叉树: "+isBCT(head));
    }

    public static class Node{
        public Node left;
        public Node right;
        public int value;
        public Node(int data ){
            this.value=data;
        }
    }

    /*
      判断是否为完全二叉树需要两个条件
      1、左孩子为空右孩子不能为空
      2、在一的条件下遇到过左右两孩子不双全的节点,当前节点不能有叶子节点
     */
    public static Boolean isBCT(Node head){
        if (head==null){
            return true;
        }
        LinkedList<Node>queue=new LinkedList<>();
        boolean leaf=false;// 是否遇到过左右两个孩子不双全的节点
        Node l=null;
        Node r=null;
        queue.add(head);
        while (!queue.isEmpty()){
            head=queue.poll();
            l=head.left;
            r=head.right;
            if(
                    (leaf && (l != null || r != null))
                    ||
                            (l==null && r!=null)
            ){
                return false;
            }
            if (l!=null){
                queue.add(l);
            }
            if (r!=null){
                queue.add(r);
            }
            if (l==null||r==null){
                leaf=true;
            }
        }
        return true;
    }

运行结果
在这里插入图片描述

五、是否为满二叉树

在这里插入图片描述

满二叉树的条件

记一棵树最大深度为L,所有节点数为N,满二叉树存在以下关系:
N=2^L-1

构建信息体,只要知道树的高度和节点个数

 public static class ReturnData{
        public boolean isF;
        public int height;
        public int nodes;
        public ReturnData(boolean isF ,int height,int nodes){
            this.height=height;
            this.nodes=nodes;
            this.isF=isF;
        }
    }

信息处理

//加工信息
    public static ReturnData process(Node x){
        if (x==null){
            return new ReturnData(true,0,0);
        }
        ReturnData leftData=process(x.left);
        ReturnData rightData=process(x.right);

        boolean isF=true;
        int height=Math.max(leftData.height,rightData.height)+1;
        int nodes=leftData.nodes+ rightData.nodes+1;
        // 是否符合 N=2^L-1
        if (nodes!=Math.pow(2,height)-1){
            isF=false;
        }
        return new ReturnData(isF,height,nodes);
    }
}

完整代码

 public static void main(String[] args) {
        Node head=new Node(1);
        head.left=new Node(2);
        head.right=new Node(3);
        head.left.left=new Node(4);
        head.left.right=new Node(5);
        head.right.left=new Node(6);
        head.right.right=new Node(7);
        head.left.left.left=new Node(8);
        head.left.left.right=new Node(9);
        head.left.right.left=new Node(10);
        head.left.right.right=new Node(11);
        head.right.left.left=new Node(12);
        head.right.left.right=new Node(13);
        head.right.right.left=new Node(14);
        head.right.right.right=new Node(15);
        System.out.println("节点数: "+process(head).nodes);
        System.out.println("高度: "+process(head).height);
        System.out.println("是否为满二叉树: "+process(head).isF);
    }
    public static class Node{
        public Node left;
        public Node right;
        public int value;
        public Node(int data){
            this.value=data;
        }
    }


    /*
    构建信息体
     */
    public static class ReturnData{
        public boolean isF;
        public int height;
        public int nodes;
        public ReturnData(boolean isF ,int height,int nodes){
            this.height=height;
            this.nodes=nodes;
            this.isF=isF;
        }
    }

    //加工信息
    public static ReturnData process(Node x){
        if (x==null){
            return new ReturnData(true,0,0);
        }
        ReturnData leftData=process(x.left);
        ReturnData rightData=process(x.right);

        boolean isF=true;
        int height=Math.max(leftData.height,rightData.height)+1;
        int nodes=leftData.nodes+ rightData.nodes+1;
        // 是否符合 N=2^L-1
        if (nodes!=Math.pow(2,height)-1){
            isF=false;
        }
        return new ReturnData(isF,height,nodes);
    }

六、是否为平衡二叉树

平衡二叉树

在这里插入图片描述

对任何一个子树来说,左数和右树的高度差不超过1。

  1. 左子树为平衡二叉树
  2. 右子树为平衡二叉树
  3. |左子树高度-右子树高度|<=1
 public static ReturnType process(Node x){
        if (x==null){
            return new ReturnType(true,0);
        }
        // 递归左右子树返回信息
        ReturnType leftData=process(x.left);
        ReturnType rightData=process(x.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 class ReturnType{ // 子树信息结构体
        public boolean isBalanced;// 是否平衡
        public int height;// 树高度
        public ReturnType(boolean isB,int height){// 构造函数
            this.isBalanced=isB;
            this.height=height;
        }
    }

完整代码:

public static void main(String[] args) {
        Node head=new Node(5);
        head.left=new Node(3);
        head.right=new Node(7);
        head.left.left=new Node(2);
        head.left.right=new Node(4);
        head.right.left=new Node(6);
        System.out.println("树高为:"+isBalanced(head).height);
        System.out.println("是否为平衡二叉树:"+isBalanced(head).isBalanced);
    }
    public static class Node{
        public Node left;
        public Node right;
        public int value;

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

    public static ReturnType isBalanced(Node  head){// 主函数
        return process(head);
    }
    public static class ReturnType{ // 子树信息结构体
        public boolean isBalanced;// 是否平衡
        public int height;// 树高度
        public ReturnType(boolean isB,int height){// 构造函数
            this.isBalanced=isB;
            this.height=height;
        }
    }
    public static ReturnType process(Node x){
        if (x==null){
            return new ReturnType(true,0);
        }
        ReturnType leftData=process(x.left);
        ReturnType rightData=process(x.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);
    }

运行结果:
在这里插入图片描述

七、二叉树题目应用

1、最低公共祖先节点

题目描述:
给定两个二叉树的节点node1和node2,找到他们最低公共祖先节点
如图G和F节点的最低公共祖先节点为C,E和G的 最低公共祖先为E。

在这里插入图片描述

解题思路:
理解版:
将其中一个节点往上回溯的其余节点和他本身放到一个集合中,如F节点往上回溯将A、C、F三个节点放入集合中,再将另一个节点往上回溯,每次回溯都去第一个集合查询是否存在该节点,没有就往上回溯,直到第一个出现在第一集合中的节点就是最低公共祖父节点,如G节点往上回溯,发现G、E不存在,最终找到C,C就是该最低祖父节点。

储存关系集合:

 //迭代将整个树关系储存
    public static void process(Node head, HashMap<Node,Node>fatherMap){
        if (head==null){
            return;
        }
        fatherMap.put(head.left,head);
        fatherMap.put(head.right,head);

        process(head.left,fatherMap);
        process(head.right,fatherMap);
    }

回溯查找:

public static Node lca(Node head,Node o1,Node o2){
        HashMap<Node,Node>fatherMap=new HashMap<>();
        fatherMap.put(head,head);
        process(head,fatherMap);//储存整棵树各个节点的回溯关系
        HashSet<Node>set1=new HashSet<>();
        HashSet<Node>set2=new HashSet<>();

        Node cur=o1;
        while (cur!=fatherMap.get(cur)){//第一个节点回溯添加
            set1.add(cur);
            cur=fatherMap.get(cur);
        }
        set1.add(head);// 将头节点添加

        cur=o2;
        while (cur!=fatherMap.get(cur)){//第二个节点回溯添加
            set2.add(cur);
            cur=fatherMap.get(cur);
        }
        for (Node node1:set2){
            for (Node node2 : set1) {
                if (node1==node2){
                    return node2;
                }
            }
        }

简易版:
1、当o1是 o2的最低公共祖先或当o2是 o1的最低公共祖先
2、o1和o2不互为公共祖先,必须向上回溯才能找到

public static Node lca2(Node head,Node o1,Node o2){
        if (head==null || head==o1 || head==o2){
            return head;
        }
        //以头节点分成左右两个树
        Node left=lca2(head.left, o1, o2);//左树返回
        Node right=lca2(head.right, o1, o2);//右树返回
        if (left!=null && right!=null){// 条件二判断
            return head;
        }
        //左右两棵树,并不都有返回值(条件一)
        return left!=null ? left:right;
    }

完整代码:

 public static void main(String[] args) {
        Node head=new Node("A");
        head.left=new Node("B");
        head.right=new Node("C");
        head.left.left=new Node("D");
        head.right.left=new Node("E");
        head.right.right=new Node("F");
        head.right.left.left=new Node("G");
        System.out.println("理解版最低祖父公共节点为:"+lca(head,head.right.left.left,head.right.right).value);
        System.out.println("简洁版最低祖父公共节点为:"+lca2(head,head.right.left.left,head.right.right).value);
    }
    public static class Node{
        public Node left;
        public Node right;
        public String value;

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

    /*
    易理解版
     */
    public static Node lca(Node head,Node o1,Node o2){
        HashMap<Node,Node>fatherMap=new HashMap<>();
        fatherMap.put(head,head);
        process(head,fatherMap);//储存整棵树各个节点的回溯关系
        HashSet<Node>set1=new HashSet<>();
        HashSet<Node>set2=new HashSet<>();

        Node cur=o1;
        while (cur!=fatherMap.get(cur)){//第一个节点回溯添加
            set1.add(cur);
            cur=fatherMap.get(cur);
        }
        set1.add(head);// 将头节点添加

        cur=o2;
        while (cur!=fatherMap.get(cur)){//第二个节点回溯添加
            set2.add(cur);
            cur=fatherMap.get(cur);
        }
        for (Node node1:set2){
            for (Node node2 : set1) {
                if (node1==node2){
                    return node2;
                }
            }
        }

        return head;
    }
    //迭代将整个树关系储存
    public static void process(Node head, HashMap<Node,Node>fatherMap){
        if (head==null){
            return;
        }
        fatherMap.put(head.left,head);
        fatherMap.put(head.right,head);

        process(head.left,fatherMap);
        process(head.right,fatherMap);
    }


    /*
    简洁版:
        1、当o1是 o2的最低公共祖先或当o2是 o1的最低公共祖先
        2、o1和o2不互为公共祖先,必须向上回溯才能找到
     */
    public static Node lca2(Node head,Node o1,Node o2){
        if (head==null || head==o1 || head==o2){
            return head;
        }
        //以头节点分成左右两个树
        Node left=lca2(head.left, o1, o2);//左树返回
        Node right=lca2(head.right, o1, o2);//右树返回
        if (left!=null && right!=null){// 条件二判断
            return head;
        }
        //左右两棵树,并不都有返回值(条件一)
        return left!=null ? left:right;
    }

运行结果:
在这里插入图片描述

2、后继节点

题目描述:
不通过中序遍历找到某个节点的后继(前继)节点
后继节点就是中序遍历的当前节点的后一个节点,前继相反
如图二叉树中序遍历为:D->B->A->G->E->C->F
则B的后继为A,前继为D
在这里插入图片描述

解题思路:

后继:

  1. 当需要找的节点有右子树时,他的后继就是右子树的最左子树(没有最左时就是本身)
  2. 当需要找的节点有右子树时,向上寻找节点,直到找到某个节点是该节点头节点的左子树时,该节点的头就是后继

根据情况一向左一直找最左子树

 // 向左寻找最左子树
    public static Node getLeftMost(Node node){
        if (node==null){
            return null;
        }
        while (node.left!=null){
            node=node.left;
        }
        return node;
    }

根据情况二找

 Node parent=node.parent;
            while (parent!=null && parent.left!=node){//当前节点是其父亲节点右孩子 情况二
                node=parent; //往上移动
                parent=node.parent;
            }
            return parent;

完整代码

public static void main(String[] args) {
        Node head=new Node("A");
        head.left=new Node("B");
        head.right=new Node("C");
        head.left.left=new Node("D");
        head.right.left=new Node("E");
        head.right.right=new Node("F");
        head.right.left.left=new Node("G");
        head.parent=null;
        head.left.parent=head;
        head.right.parent=head;
        head.left.left.parent=head.left;
        head.right.left.parent=head.right;
        head.right.right.parent=head.right;
        head.right.left.left.parent=head.right.left;
        System.out.println("G节点的后继为:"+getSuccessorNode(head.right.left.left).value);
    }
    public static class Node{
        public String value;
        public Node left;
        public Node right;
        public Node parent;// 指向自己的父节点
        public Node(String value){
            this.value=value;
        }
    }
    public static Node getSuccessorNode(Node node){
        if (node==null){
            return null;
        }
        if (node.right!=null){//情况一
            return getLeftMost(node.right);
        }else {//无右子树
            Node parent=node.parent;
            while (parent!=null && parent.left!=node){//当前节点是其父亲节点右孩子 情况二
                node=parent; //往上移动
                parent=node.parent;
            }
            return parent;
        }
    }
    // 向左寻找最左子树
    public static Node getLeftMost(Node node){
        if (node==null){
            return null;
        }
        while (node.left!=null){
            node=node.left;
        }
        return node;
    }

运行结果
在这里插入图片描述

3、二叉树的序列化与反序列化

题目描述:
从字符串到内存结构的转换叫反序列化,从内存结构到字符串的转换叫序列化
以‘#’表示null,节点之间用’_'隔开
如图所示二叉树的先序为:A_B_D_C_E_G_F
在这里插入图片描述

(1)二叉树的序列化

 public static String serialByPre(Node head){
        if (head==null){
            return "#_";
        }
        String res=head.value+"_";
        res+=serialByPre(head.left);
        res+=serialByPre(head.right);
        return res;
    }

运行结果
在这里插入图片描述

(1)二叉树的反序列化

//反序列化主函数
    public static Node reconByPreString(String preStr){
        String[]values=preStr.split("_");
        Queue<String> queue = new LinkedList<String>(Arrays.asList(values));//将每一项复制给队列
        return reconPreOrder(queue);
    }
    //反序列化处理
    public static Node reconPreOrder(Queue<String>queue){
        String value=queue.poll();
        if (Objects.equals(value, "#")){
            return null;
        }
        Node head=new Node(value);
        head.left=reconPreOrder(queue);//左树反序列
        head.right=reconPreOrder(queue);//右树反序列
        return head;
    }

4、折纸条问题

问题描述:
一个纸条向自己的方向向上折N次,依次打印折痕方向(折痕向外为‘凹’,向内为‘凸’)。

如折一次时,纸条的折痕为‘凹’;折两次时,折痕为‘凹凹凸’;三次时,折痕为‘凹凹凸凹凹凸凸’。

在这里插入图片描述

解题思路:
经过模拟发现折痕是一颗总头节点为‘凹’ 左子树为‘凹’,右子树为‘凸’的满树,如果打印折痕就是将这棵树中序遍历。

代码实现

public static void main(String[] args) {
        int N=3;
        printAllFolds(N);
    }
    public static void printAllFolds(int N){
        printProcess(1,N,true);
    }
    /*
       i为节点层数
       N为共几层
       down == true 凹
       down == false 凸
     */

    public static void printProcess(int i,int N,boolean down){
        if (i>N){// 超过就返回
            return;
        }
        //中序遍历
        printProcess(i+1,N,true);
        System.out.println(down?"凹":"凸");
        printProcess(i+1,N,false);
    }

运行结果
在这里插入图片描述

总结

本文简单介绍了二叉树的三种遍历,以及相关二叉树的识别以及一些二叉树的应用题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天将降大任于我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值