ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二叉树的六种遍历

2021-12-16 11:02:51  阅读:146  来源: 互联网

标签:node Node 遍历 六种 System 二叉树 println out


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]]

标签:node,Node,遍历,六种,System,二叉树,println,out
来源: https://www.cnblogs.com/revol/p/15696868.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有