二叉树

知识点

1.二叉树结构

class Node{

    int value;
    Node left;
    node right;

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


}

2.二叉树常考题型

  • 易结合队列、栈,数组、链表等数据结构出题
  • 掌握图的基本遍历方式,深度优先与广度优先
  • 需要掌握递归函数的使用,自己设计递归过程
  • 与实际工作结合紧密

3.遍历类型

  • 先序遍历:中,左,右
  • 中序遍历:左,中,右
  • 后序遍历:左,右,根

    结合下图讲解:

    这里写图片描述

先序遍历:1245367
中序遍历:4251637
后序遍历:4526731

递归二叉树的序列打印

题目:
请用递归方式实现二叉树的先序、中序和后序的遍历打印。

给定一个二叉树的根结点root,请依次返回二叉树的先序,中序和后续遍历(二维数组的形式)。

代码:

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
public class TreeToSequence {
    public int[][] convert(TreeNode root) {
        //边界条件判定
        if(root==null){
            return null;
        }

        List<Integer>  preResult = new ArrayList<Integer>();
        List<Integer>  midResult = new ArrayList<Integer>();
        List<Integer>  lastResult = new ArrayList<Integer>();
        preOrderTree(root,preResult);
        midOrderTree(root,midResult);
        lastOrderTree(root,lastResult);

        //结果数组

        int[][] resultArr = new int[3][preResult.size()];
        resultArr[0] = listToArray(preResult);
        resultArr[1] = listToArray(midResult);
        resultArr[2] = listToArray(lastResult);

        return resultArr;

    }


    //先序遍历
    public void preOrderTree(TreeNode root,List<Integer> preResult){


        if(root==null){
            return;
        }

        preResult.add(root.val);
        preOrderTree(root.left,preResult);
        preOrderTree(root.right,preResult);
    }

   //中序遍历
    public void midOrderTree(TreeNode root,List<Integer> midResult){


        if(root==null){
            return;
        }

        midOrderTree(root.left,midResult);
        midResult.add(root.val);
        midOrderTree(root.right,midResult);

    }

    //后遍历
    public void lastOrderTree(TreeNode root,List<Integer> lastResult){

        if(root==null){
            return;
        }

        lastOrderTree(root.left,lastResult);
        lastOrderTree(root.right,lastResult);
        lastResult.add(root.val);
    }


    //list转化为数组
    public int[] listToArray(List<Integer> list){
        int[] temp = new int[list.size()];
        for(int j=0;j<list.size();j++){
            temp[j] = list.get(j);
        }

        return temp;

    }



}

非递归打印

题目:
请用非递归方式实现二叉树的先序、中序和后序的遍历打印。

给定一个二叉树的根结点root,请依次返回二叉树的先序,中序和后续遍历(二维数组的形式)。

代码:

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
public class TreeToSequence {
    public int[][] convert(TreeNode root) {
        //边界条件判断
        if(root==null){
            return null;
        }

        List<Integer> preList = new ArrayList<Integer>();
        List<Integer> midList = new ArrayList<Integer>();
        List<Integer> lastList = new ArrayList<Integer>();

        preOrderTree(root,preList);
        midOrderTree(root,midList);
        lastOrderTree(root,lastList);

        int[][] result = new int[3][];
        result[0] = listToArray(preList);
        result[1] = listToArray(midList);
        result[2] = listToArray(lastList);

        return result;
    }

    //先序遍历
    public void preOrderTree(TreeNode root,List<Integer> list){

        if(root==null){
            return;
        }

        //申请一个新的栈结构
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        //定义一个临时存储节点
        TreeNode temp = null;

        while(!stack.empty()){
            temp = stack.pop();
            list.add(temp.val);
            if(temp.right!=null){
                stack.push(temp.right);
            }

            if(temp.left!=null){
                stack.push(temp.left);
            }
        } 
    }

    //中序遍历
    public void midOrderTree(TreeNode root,List<Integer> list){
        if(root==null){
            return;
        }

        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode cur = root;

        while(!stack.empty()||cur!=null){

            if(cur!=null){

                stack.push(cur);
                cur = cur.left;

            }else{

                cur = stack.pop();
                list.add(cur.val);
                cur = cur.right;


            }
        }
    }  
   //后序遍历
    public void lastOrderTree(TreeNode root,List<Integer> list){

        if(root==null){
            return;
        }

        Stack<TreeNode> stack1 = new Stack<TreeNode>();
        Stack<TreeNode> stack2 = new Stack<TreeNode>();
        stack1.push(root);

        while(!stack1.empty()){

           TreeNode temp = stack1.pop();
           stack2.push(temp);
           if(temp.left!=null){
               stack1.push(temp.left);
           }

           if(temp.right!=null){
               stack1.push(temp.right);
           }

        }

        while(!stack2.empty()){

            list.add(stack2.pop().val);
        }

    }

    //list转化为数组
    public int[] listToArray(List<Integer> list){
        int[] temp = new int[list.size()];
        for(int j=0;j<list.size();j++){
            temp[j] = list.get(j);
        }

        return temp;

    }


}

二叉树的分层换行打印

题目:
有一棵二叉树,请设计一个算法,按照层次打印这棵二叉树。

给定二叉树的根结点root,请返回打印结果,结果按照每一层一个数组进行储存,所有数组的顺序按照层数从上往下,且每一层的数组内元素按照从左往右排列。保证结点数小于等于500。

代码:

    import java.util.*;

    /*
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;
        public TreeNode(int val) {
            this.val = val;
        }
    }*/
    public class TreePrinter {
        public int[][] printTree(TreeNode root) {
            //边界条件判断
            if(root==null){
                return null;
            }
            //存储分层打印结果
            ArrayList<ArrayList<TreeNode>> resultList = new ArrayList<ArrayList<TreeNode>>();
            //用于判断换行的两个变量
            //last表示每行的最后一个元素
            //nLast表示当前遍历到的节点
            TreeNode last = root;
            TreeNode nLast = root;
            //模拟队列,宽度优先
            LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
            queue.addFirst(root);
            //存储每一行的元素的临时结构
            ArrayList<TreeNode> tempList = new ArrayList<TreeNode>();

            while(queue.size()!=0){
                //每次弹出头部元素
                TreeNode temp = queue.pollFirst();
                tempList.add(temp);

                //左孩子不空,加入队列
                if(temp.left!=null){
                  queue.addLast(temp.left);
                  nLast = temp.left;
                }
                //右孩子不空,加入队列
                 if(temp.right!=null){
                  queue.addLast(temp.right); 
                  nLast = temp.right;
                }
                //若last=temp,说明遍历到了行尾元素,换行,并将last下移到下一行的末尾
                if(last==temp){
                    last = nLast;
                    resultList.add(tempList);
                    tempList = new ArrayList<TreeNode>();
                }

            }

           //list转化为数组
            int[][] result = new int[resultList.size()][];

            for(int i=0;i<resultList.size();i++){

                result[i] = new int[resultList.get(i).size()];

                for(int j=0;j<resultList.get(i).size();j++){
                    result[i][j] = resultList.get(i).get(j).val;
                }  

            }

            return result;

        }
    }

二叉树的序列化问题

题目:
首先我们介绍二叉树先序序列化的方式,假设序列化的结果字符串为str,初始时str等于空字符串。先序遍历二叉树,如果遇到空节点,就在str的末尾加上“#!”,“#”表示这个节点为空,节点值不存在,当然你也可以用其他的特殊字符,“!”表示一个值的结束。如果遇到不为空的节点,假设节点值为3,就在str的末尾加上“3!”。现在请你实现树的先序序列化。

给定树的根结点root,请返回二叉树序列化后的字符串。

代码:

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
public class TreeToString {
    public String toString(TreeNode root) {
        //边界条件判定
        if(root==null){
            return "#!";
        }

        StringBuffer sb = new StringBuffer();
        preOrder(root,sb);

        return sb.toString();

    }

   public void preOrder(TreeNode root,StringBuffer sb){

       if(root==null){
           sb.append("#!");
       }else{

           sb.append(root.val+"!");
           preOrder(root.left,sb);
           preOrder(root.right,sb);

       }


   }
}

折纸练习题

题目:
请把纸条竖着放在桌⼦上,然后从纸条的下边向上⽅对折,压出折痕后再展 开。此时有1条折痕,突起的⽅向指向纸条的背⾯,这条折痕叫做“下”折痕 ;突起的⽅向指向纸条正⾯的折痕叫做“上”折痕。如果每次都从下边向上⽅ 对折,对折N次。请从上到下计算出所有折痕的⽅向。

给定折的次数n,请返回从上到下的折痕的数组,若为下折痕则对应元素为”down”,若为上折痕则为”up”.

测试样例:
1
返回:[“down”]

代码:

import java.util.*;

public class FoldPaper {
    public String[] foldPaper(int n) {
        //边界条件判定
        if(n<=0){
            return null;
        }

        ArrayList<String> result = new ArrayList<String>();
        fold(1,n,true,result);

        String[] str = new String[result.size()];
        for(int i = 0; i < result.size(); i++){
            str[i] = result.get(i);
        }

        return str;

    }


    public void fold(int i,int n,boolean down,ArrayList<String> list){
        //判断边界,是否大于给定次数n
        if(i>n){
            return;
        }
        //,折纸的折痕顺序为中序遍历结果,左边的孩子全为下折痕,右边的孩子全为上折痕
        fold(i+1,n,true,list);
        list.add(down == true?"down":"up");
        fold(i+1,n,false,list);

    }
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值