JAVA面试之二叉树问题

**最近刷面试题的时候发现各大公司对二叉树的算法情有独钟,所以花时间研究了一下,用JAVA实现了包括二叉树的添加节点,前序中序后序遍历,按层遍历,以及树的深度的计算。
在贴代码之前对树的原意考的基本理念复习一下。**

  1. 树是属于一种非线性的数据结构
  2. 存储分为顺序存储用数组和链式存储
  3. 树通常研究的是二叉树
  4. 二叉树又分为二叉堆和二叉查找树
  5. 二叉堆一般用顺序存储来进行存储 因为二叉堆一般都是完全二叉树
    用顺序存储比较节省空间并且对上溢和下溢的操作也相对容易通过对索引进行操作
  6. 二叉堆特点父节点大于左孩子及右孩子
  7. 二叉查找树一般用链式存储来进行操作 这也是我们通常用的
  8. 左孩子小于当前节点 右孩子大于当前节点
    下面就是对二叉查找树的一系列操作了

    一 节点类的构建

public class Node {
    private String data;//当前值
    private Node leftNode;//左孩子
    private Node rightNode;//右孩子

    public Node(){

    }
    public Node(String data,Node leftNode,Node rightNode){
        this.data = data;
        this.leftNode = leftNode;
        this.rightNode = rightNode;
    }
    public String getData() {
        return data;
    }
    public void setData(String data) {
        this.data = data;
    }
    public Node getLeftNode() {
        return leftNode;
    }
    public void setLeftNode(Node leftNode) {
        this.leftNode = leftNode;
    }
    public Node getRightNode() {
        return rightNode;
    }
    public void setRightNode(Node rightNode) {
        this.rightNode = rightNode;
    }
}

二。树的一系列操作 注释写的很清楚

import java.util.LinkedList;

public class Tree {
    public Node root;

    //构建一个二叉树 插入
    public void add(String data){
        Node node = new Node(data,null,null);
        Node parent = root;
        Node current = root;
        boolean flag = true;
        //判断根节点是否有值
        if(root == null){
            root = node;
        }else{
            //一直判断当前比较节点是否不为空,为空的话就可以进行插入啦
            while(current !=null){
                //假如小于根节点
                parent = current;
                if(data.compareTo(current.getData())<0){
                    current = current.getLeftNode();
                    flag = true;
                //假如大于根节点
                }else if(data.compareTo(current.getData())>0){
                    current = current.getRightNode();
                    flag = false;
                //假如树中有值则不插入
                }else{
                    return ;
                }
            }
            if(flag){
                current = node;
                parent.setLeftNode(current);
            }else{
                current = node;
                parent.setRightNode(current);
            }
        }
    }

    //前序遍历
    public void search_DLR(Node root){
        if(root != null){
            System.out.print(root.getData()+" ");
            search_DLR(root.getLeftNode());
            search_DLR(root.getRightNode());
        }
    }
    //中序遍历
    public void search_LDR(Node root){
        if(root !=null){
            search_LDR(root.getLeftNode());
            System.out.print(root.getData()+" ");
            search_LDR(root.getRightNode());
        }
    }
    //后序遍历
    public void search_LRD(Node root){
        if(root !=null){
            search_LRD(root.getLeftNode());
            search_LRD(root.getRightNode());
            System.out.print(root.getData()+" ");
        }
    }
    //按层进行遍历
    /*
     * 总体思路就是把树种节点存入到linkedlist模拟的队列中去
     * 把头元素移出的同时把它的左右孩子插入到队列当中去 如果有的话
     * 这样不断进行这个操作 弹出头结点的同时输出头结点知道队列为空 按层遍历
     */
    public void search_level(Node root){
        //把数据存到一个队列里面 这里面用链表来模拟队列
        LinkedList list = new LinkedList();
        Node node  = root;
        Node result = null;
        //先把根节点插入进去 判断根节点是否有值
        if(node != null){
            list.addLast(node);
            //弹出根节点值
            result = list.poll();
            //不断判断弹出节点的返回值 如果没有节点了则弹出null 做终止判断
            while(result!=null){
                System.out.print(result.getData()+" ");
                //判断当前队列中第一个元素是否含有左右孩子如果含有则插入到队列中
                if(node.getLeftNode()!=null){
                    list.addLast(node.getLeftNode());
                }
                if(node.getRightNode()!=null){
                    list.addLast(node.getRightNode());
                }
                //当前队列不为空时 node变量始终指向队列头元素
                if(list.size() != 0){
                    node = list.getFirst();
                }
                //弹出头元素并循环判断其是否为空是否含有左右孩子
                result = list.poll();
            }
        }
        else{
            System.out.println("当前为空树");
        }
    }
    //查找当前树的深度 如果根节点为空则深度为0 如果不为空 递归调用左右孩子比较谁大谁大就返回谁
    public int search_depth(Node root){
        if(root == null){
            return 0;
        }else{
            int left = 1;
            int right = 1;
            left += search_depth(root.getLeftNode());
            right += search_depth(root.getRightNode());
            return left>right?left:right;
        }
    }
    //获取某一元素的结点 及其左孩子和右孩子
    public Node searchByData(String data){
        Node node = this.root;
        Node result = null;
        if(node.getData().equals(data)){
            result = node;
        }else{
            //判断当前节点与目标节点的大小比值 
            while(node!=null && node.getData().compareTo(data)<0){
                node = node.getRightNode();
            }
            while(node!=null && node.getData().compareTo(data)>0 ){
                node = node.getLeftNode();
            }
            if(node !=null){
                result = node;
            }
        }
        return result;
    }

    public static void main(String[] args){
        //测试代码
        Tree tree = new Tree();
        tree.add("4");
        tree.add("6");
        tree.add("2");
        tree.add("3");
        tree.add("7");
        tree.add("8");
        tree.add("5");
        System.out.println("前序遍历");
        tree.search_DLR(tree.getRoot());
        System.out.println();
        System.out.println("中序遍历");
        tree.search_LDR(tree.getRoot());
        System.out.println();
        System.out.println("后序遍历");
        tree.search_LRD(tree.getRoot());
        System.out.println();
        System.out.println("按层遍历");
        tree.search_level(tree.getRoot());
        System.out.println();
        System.out.println("当前树的深度");
        System.out.println(tree.search_depth(tree.getRoot()));
        System.out.println("查找某一元素");
        Node node = tree.searchByData("6");
        if(node!=null){
            System.out.println("当前元素为"+node.getData()+"  左孩子为"+node.getLeftNode().getData()+"  右孩子为"+node.getRightNode().getData());
        }else{
            System.out.println("当前元素不存在");
        }

    }

    public Node getRoot() {
        return root;
    }

}

三。输出的效果
JAVA面试之二叉树问题_第1张图片

欢迎大家批评指正。

你可能感兴趣的:(数据结构)