二叉树的六种遍历

Node:

package com.test.node;

/**
 * @author :wdl
 * @date :Created in 2021-12-06 14:31
 * @description:模拟二叉树节点
 */
public class Node {
    private int value;        //节点的值
    private Node node;        //此节点,数据类型为Node
    private Node left;        //此节点的左子节点,数据类型为Node
    private Node right;       //此节点的右子节点,数据类型为Node

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public Node getNode() {
        return node;
    }

    public void setNode(Node node) {
        this.node = node;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    public Node(int value) {
        this.value=value;
        this.left=null;
        this.right=null;
    }
    public String toString() {         //自定义的toString方法,为了方便之后的输出
        return this.value+" ";
    }
}

java - Test:

package com.test.node;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

/**
 * @author :wdl
 * @date :Created in 2021-12-06 14:32
 * @description:测试
 */
public class Test {

    public static void main(String[] args) {
        int[] ints = {0,1,2,3,4,5,6,7,8,9};
        ArrayList<Node> nodes = new ArrayList<>();
        create(ints,nodes);

        Node node = nodes.get(0);
        System.out.println("数组转二叉树");
        print(node);

        System.out.println("");
        System.out.println("递归前序遍历");
        preTraversal(node);

        System.out.println("");System.out.println("");
        System.out.println("递归中序遍历");
        midTraversal(node);

        System.out.println("");System.out.println("");
        System.out.println("递归后序遍历");
        postTraversal(node);

        System.out.println("");System.out.println("");
        System.out.println("非递归前序遍历");
        preOrderTraversalbyLoop(node);

        System.out.println("");System.out.println("");
        System.out.println("非递归中序遍历");
        inOrderTraversalbyLoop(node);

        System.out.println("");System.out.println("");
        System.out.println("非递归后序遍历");
        postOrderTraversalbyLoop(node);

        System.out.println("");System.out.println("");
        System.out.println("广度优先遍历");
        bfs(node);

        System.out.println("");System.out.println("");
        System.out.println("深度度优先遍历");
        List<Integer> intArr = new ArrayList<>();
        List<Integer> intArr2 = new ArrayList<>();
        List<List<Integer>> intArrs = new ArrayList<>();
        intArrs.add(intArr);
        dfs(node,intArrs, intArr2);
        System.out.println(intArrs);

    }
    public static void print(Node... node){
        ArrayList<Node> nodes = new ArrayList<Node>();
        for (Node node1 : node) {
            System.out.print(node1.getValue()+" ");
            Node left = node1.getLeft();
            Node right = node1.getRight();
            if(left != null) nodes.add(left);
            if(right != null) nodes.add(right);
        }
        System.out.println("");
        if(nodes.size()>0){
            print(nodes.toArray(new Node[]{}));
        }
    }

    /**
     * 数组升华二叉树
     * @param datas
     * @param list
     */
    public  static void create(int[] datas, List<Node> list) {

        //将数组里面的东西变成节点的形式
        for(int i=0;i<datas.length;i++) {
            Node node=new Node(datas[i]);
            list.add(node);
        }

        //节点关联成树
        for(int index=0;index<list.size()/2-1;index++) {
            list.get(index).setLeft(list.get(index*2+1));
            //编号为n的节点他的左子节点编号为2*n 右子节点编号为2*n+1 但是因为list从0开始编号,所以还要+1
            list.get(index).setRight(list.get(index*2+2));  //与上同理
        }

        //单独处理最后一个父节点 ,list.size()/2-1进行设置,避免单孩子情况
        int index=list.size()/2-1;
        list.get(index).setLeft(list.get(index*2+1));
        if(list.size()%2==1)
            //如果有奇数个节点,最后一个父节点才有右子节点
            list.get(index).setRight(list.get(index*2+2));

    }

    /**
     * 递归前序遍历
     * @param node
     */
    public static void preTraversal(Node node){
        if (node == null) //很重要,必须加上 当遇到叶子节点用来停止向下遍历
            return;
        System.out.print(node.getValue()+" ");
        preTraversal(node.getLeft());
        preTraversal(node.getRight());
    }

    /**
     * 递归中序遍历
     * @param node
     */
    public static void midTraversal(Node node){
        if (node == null)
            return;
        midTraversal(node.getLeft());
        System.out.print(node.getValue()+" ");
        midTraversal(node.getRight());
    }

    /**
     * 递归后序遍历
     * @param node
     */
    public static void postTraversal(Node node){
        if (node == null)
            return;
        postTraversal(node.getLeft());
        postTraversal(node.getRight());
        System.out.print(node.getValue()+" ");
    }

    /**
     * 非递归前序遍历
     * @param node
     */
    public static void preOrderTraversalbyLoop(Node node){
        Stack<Node> stack = new Stack();
        Node p = node;
        while(p!=null || !stack.isEmpty()){
            while(p!=null){
                //当p不为空时,就读取p的值,并不断更新p为其左子节点,即不断读取左子节点
                System.out.print(p.getValue()+" ");
                stack.push(p); //将p入栈
                p = p.getLeft();
            }
            if(!stack.isEmpty()){
                p = stack.pop();
                p = p.getRight();
            }
        }
    }

    /**
     * 非递归中序遍历
     * @param node
     */
    public static void inOrderTraversalbyLoop(Node node){
        Stack<Node> stack = new Stack();
        Node p = node;
        while(p!=null || !stack.isEmpty()){
            while(p!=null){
                stack.push(p);
                p = p.getLeft();
            }
            if(!stack.isEmpty()){
                p = stack.pop();
                System.out.print(p.getValue()+" ");
                p = p.getRight();
            }
        }
    }

    /**
     * 非递归后序遍历
     * @param node
     */
    public static void postOrderTraversalbyLoop(Node node){

        Stack<Node> stack = new Stack<Node>();
        Node p = node,    prev = node;
        while(p!=null || !stack.isEmpty()){
            while(p!=null){
                stack.push(p);
                p = p.getLeft();
            }
            if(!stack.isEmpty()){
                Node temp = stack.peek().getRight();
                //只是拿出来栈顶这个值,并没有进行删除
                if(temp == null||temp == prev){
                    //节点没有右子节点或者到达根节点【考虑到最后一种情况】
                    p = stack.pop();
                    System.out.print(p.getValue()+" ");
                    prev = p;
                    p = null;
                }
                else{
                    p = temp;
                }
            }
        }
    }

    /**
     * 广度优先遍历
     * @param root
     */
    public static void bfs(Node root){
        if(root == null) return;
        LinkedList<Node> queue = new LinkedList<Node>();
        queue.offer(root); //首先将根节点存入队列
        //当队列里有值时,每次取出队首的node打印,打印之后判断node是否有子节点,若有,则将子节点加入队列
        while(queue.size() > 0){
            Node node = queue.peek();
            queue.poll();//取出队首元素并打印
            System.out.print(node.getValue()+" ");
            if(node.getLeft() != null){ //如果有左子节点,则将其存入队列
                queue.offer(node.getLeft());
            }
            if(node.getRight() != null){ //如果有右子节点,则将其存入队列
                queue.offer(node.getRight());
            }
        }
    }

    /**
     * 深度优先遍历
     */
    public static void dfs(Node node,List<List<Integer>> rst,List<Integer> list){
        if(node == null) return;
        if(node.getLeft() == null && node.getRight() == null){
            list.add(node.getValue());
            /* 这里将list存入rst中时,不能直接将list存入,而是通过新建一个list来实现,
             * 因为如果直接用list的话,后面remove的时候也会将其最后一个存的节点删掉
             * */
            rst.add(new ArrayList<>(list));
            list.remove(list.size()-1);
        }
        list.add(node.getValue());
        dfs(node.getLeft(),rst,list);
        dfs(node.getRight(),rst,list);
        list.remove(list.size()-1);
    }
}

Result:

数组转二叉树
0 
1 2 
3 4 5 6 
7 8 9 

递归前序遍历
0 1 3 7 8 4 9 2 5 6 

递归中序遍历
7 3 8 1 9 4 0 5 2 6 

递归后序遍历
7 8 3 9 4 1 5 6 2 0 

非递归前序遍历
0 1 3 7 8 4 9 2 5 6 

非递归中序遍历
7 3 8 1 9 4 0 5 2 6 

非递归后序遍历
7 8 3 9 4 1 5 6 2 0 

广度优先遍历
0 1 2 3 4 5 6 7 8 9 

深度度优先遍历
[[], [0, 1, 3, 7], [0, 1, 3, 8], [0, 1, 4, 9], [0, 2, 5], [0, 2, 6]]
posted @ 2021-12-16 10:53  栋_RevoL  阅读(36)  评论(0编辑  收藏  举报