二叉树是什么?

二叉树是一种非常重要的数据结构,很多数据结构都是基于二叉树的基础演变而来的。二叉树有两种,深度遍历和广度遍历:

深度遍历有前序、中序以及后序三种遍历方法,广度遍历即寻常所说的层次遍历。由于树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历,不仅容易理解,而且代码非常简洁。

广度遍历则需要其他数据结构的支撑,比方堆。所以,对一段代码而言,可读性往往比代码本身的效率要重要得多。

二叉树遍历的应用:

(1)前序遍历:可以用来实现目录结构的显示。

(2)中序遍历:可以用来做表达式树,在编译器底层实现的时候用户可以实现基本的加减乘除,比如 a*b+c。

(3)后序遍历可以用来实现计算目录内的文件占用的数据大小。

(4)层次遍历可用来解决计算机游戏中找寻路径的问题,如解谜宫。

四种基本的遍历思想为:

前序遍历:根结点 ---> 左子树 ---> 右子树

中序遍历:左子树---> 根结点 ---> 右子树

后序遍历:左子树 ---> 右子树 ---> 根结点

层次遍历:仅仅需按层次遍历就可以

  新建节点

向上滑动阅览

public class Node {
  private String data;  
    private Node leftNode;  
    private Node rightNode;  
    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;  
    }  
}

初始化界节点

向上滑动阅览

public Node init() {//注意必须逆序建立,先建立子节点,再逆序往上建立,因为非叶子结点会使用到下面的节点,而初始化是按顺序初始化的,不逆序建立会报错  

      

Node H = new Node("H", null, null);  
        Node D = new Node("D", H, null);  
        Node E = new Node("E", null, null);
        Node B = new Node("B", D, E);  
        Node F = new Node("F", null, null);
        Node G = new Node("G", null, null);  
        Node C = new Node("C", F, G);  
        Node A = new Node("A", B, C);  
        return A;   //返回根节点  
    }

1. 前序遍历

递归

向上滑动阅览

public void theFirstTraversal(Node root) {  //先序遍历  
        printNode(root);  
        if (root.getLeftNode() != null) {  //使用递归进行遍历左孩子  
            theFirstTraversal(root.getLeftNode());  
        }  
        if (root.getRightNode() != null) {  //递归遍历右孩子  
            theFirstTraversal(root.getRightNode());  
        }  
    }

非递归

向上滑动阅览

public void theFirstTraversal_Stack(Node root) {  //先序遍历  
        Stack stack = new Stack();  
        Node node = root;  
        while (node != null || stack.size() > 0) {  //将所有左孩子压栈  
            if (node != null) {   //压栈之前先访问  
                printNode(node);  
                stack.push(node);  
                node = node.getLeftNode();  
            } else {  
                node = stack.pop();  
                node = node.getRightNode();  
            }  
        }  
    }

2.中序遍历

递归

向上滑动阅览

public void theInOrderTraversal(Node root) {  //中序遍历  
        if (root.getLeftNode() != null) {  
            theInOrderTraversal(root.getLeftNode());  
        }  
        printNode(root);  
        if (root.getRightNode() != null) {  
            theInOrderTraversal(root.getRightNode());  
        }  
    }

非递归

向上滑动阅览

public void theInOrderTraversal_Stack(Node root) {  //中序遍历  
        Stack stack = new Stack();  
        Node node = root;  
        while (node != null || stack.size() > 0) {  
            if (node != null) {  
                stack.push(node);   //直接压栈  
                node = node.getLeftNode();  
            } else {  
                node = stack.pop(); //出栈并访问  
                printNode(node);  
                node = node.getRightNode();
            }  
        }  
    }

3.后序遍历

递归

向上滑动阅览

public void thePostOrderTraversal(Node root) {  //后序遍历  
        if (root.getLeftNode() != null) {  
            thePostOrderTraversal(root.getLeftNode());  
        }  
        if(root.getRightNode() != null) {  
            thePostOrderTraversal(root.getRightNode());  
        }  
        printNode(root);  
    }

非递归

向上滑动阅览

public void thePostOrderTraversal_Stack(Node root) {   //后序遍历  
        Stack stack = new Stack();  
        Stack output = new Stack();//构造一个中间栈来存储逆后序遍历的结果  
        Node node = root;  
        while (node != null || stack.size() > 0) {  
            if (node != null) {  
                output.push(node);  
                stack.push(node);                 
                node = node.getRightNode();  
            } else {  
                node = stack.pop();               
                node = node.getLeftNode();
            }  
        }  
//         System.out.println(output.size());
        while (output.size() > 0) {
            printNode(output.pop());
        }  
    }

4. 层次遍历

向上滑动阅览

//层次遍历
    public static void theLeverTraversal(Node root) {
        if (root == null) {
            return;
        }
        //新建一个队列,LinkedList实现了Quene接口,可以直接当作队列来用
        LinkedList queue = new LinkedList();
        Node current;  //当前节点
        queue.offer(root);//根节点入队列
        while (!queue.isEmpty()) {
            current = queue.poll();  //取出队列的头节点
            System.out.print(current.getData() + " ");//输出队列的头节点的值
            if (current.getLeftNode() != null) {
                queue.offer(current.getLeftNode());  //如果当前节点的左节点不为空,则左节点入队列
            }
            if (current.getRightNode() != null) {
                queue.offer(current.getRightNode()); //如果当前节点的右节点不为空,则右节点入队列
            }
        }
    }