Java 实现二叉树Java 实现二叉树的先序、中序、后序、层序遍历,用递归和非递归方法

Java 实现二叉树的先序、中序、后序、层序遍历,用递归和非递归方法

欢迎大佬指导


import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class BinaryTree { //二叉树的实现类
    private class Node { //数据结构中必须有Node类
        @SuppressWarnings({ "rawtypes", "unused" })
        private Comparable data; 
        private Node left;
        private Node right;
        @SuppressWarnings("rawtypes")
        public Node(Comparable data2) {  //constructor
            this.data = data2;
        }
        @SuppressWarnings("unchecked")
        public void add(Node newNode) { //添加节点
            if (this.data.compareTo(newNode.data) > 0) { //如果小于当前节点值,放在左儿子
                if (this.left == null) { //如果左儿子为空
                    this.left = newNode;
                } else { //如果左儿子不为空,继续向下递归实现
                    this.left.add(newNode);
                }
            } else { //如果大于或等于当前节点值,放在右儿子
                if (this.right == null) { 
                    this.right = newNode;
                } else {
                    this.right.add(newNode);
                }
            }

        }
        public void toArrayNode() { //中序遍历
            if (this.left!=null) { //有左节点
                this.left.toArrayNode();
            }
            BinaryTree.this.retData[BinaryTree.this.foot++] = this.data;
            if (this.right!=null) {
                this.right.toArrayNode(); 
            }
        }
        public void PretoArray() { //先序遍历
            BinaryTree.this.retData[BinaryTree.this.foot++] = this.data;    
            if (this.left!=null) {
                this.left.PretoArray();
            }
            if (this.right!=null) {
                this.right.PretoArray();
            }
        }
        public void PosttoArray() { //后序遍历
            if (this.left!=null) {
                this.left.PosttoArray();
            } 
            if (this.right!=null) {
                this.right.PosttoArray();;
            }
            BinaryTree.this.retData[BinaryTree.this.foot++] = this.data;
        }
    }

    //*********** 编写BinaryTree操作 ***********
    private Node root; //必须保留根节点
    private int count = 0; //保留节点个数
    private int foot = 0;  //数组下标
    private Object [] retData ;
    @SuppressWarnings("rawtypes")
    public void add(Object obj) { //添加数据
        Comparable data = (Comparable)obj; //转型位Comparable类型,不然会报错
        Node newNode = new Node(data); //把当前数值添加位Node类
        if (this.root == null) { //如果根节点为空,添加为根节点
            this.root = newNode;
        } else {
            this.root.add(newNode); //否则交给 Node类实现
        }
        this.count ++;
    }
    public Object [] toArray() {   //中序输出节点数值
        if ( this.count > 0 ) {
            this.foot = 0; //输出标记(下标),
            this.retData = new Object[this.count];
            this.root.toArrayNode();
            return this.retData ;
        } else {
            return null;
        }
    }
    public Object [] PretoArray() { //先序输出节点数值
        if (this.count > 0) {
            this.foot = 0;
            this.retData = new Object[this.count];
            this.root.PretoArray();
            return this.retData;
        } else {
            return null;
        }
    }
    public Object[] PosttoArray() { //后序输出节点数值
        if (this.count > 0) {
            this.foot = 0;
            this.retData = new Object[this.count];
            this.root.PosttoArray();
            return this.retData;
        } else {
            return null;
        }
    }
    public Object[] LevertoArray() { //层序输出节点数值(数组)(非递归)
        if (this.count > 0) {
            Queue<Node> Q = new LinkedList<>();
            this.foot = 0;
            Q.add(this.root);
            while (!Q.isEmpty()) {
                int len = Q.size();
                for (int i=0; i<len; i++) {
                    Node temp = Q.poll();
                    this.retData[foot++] = temp.data;
                    if (temp.left!=null) Q.add(temp.left);
                    if (temp.right!=null) Q.add(temp.right);
                }
            }
            return this.retData;
        } else {
            return null;
        }
    }
    public void LeverOrder() { //层序遍历(非递归)
        if (this.count > 0) {
            Queue<Node> Q = new LinkedList<>();
            Q.add(this.root);
            while (!Q.isEmpty()) {
                int len = Q.size();
                for (int i=0; i<len; i++) {
                    Node temp = Q.poll();
                    System.out.print(temp.data+" ");
                    if (temp.left!=null) Q.add(temp.left);
                    if (temp.right!=null) Q.add(temp.right);
                }
            }
        } else {
            return ;
        }
    }
    /*
     * 用栈实现循环先序遍历二叉树 
     * 这种实现类似于图的深度优先遍历(DFS) 
     * 维护一个栈,将根节点入栈,然后只要栈不为空,出栈并访问,接着依次将访问节点的右节点、左节点入栈。 
     * 这种方式应该是对先序遍历的一种特殊实现(看上去简单明了),但是不具备很好的扩展性,在中序和后序方式中不适用 
     */
    public void preOrderStack_1() { //先序遍历(非递归)
        if (this.root==null)
            return ;
        Stack<Node> S = new Stack<>();
        S.push(this.root);
        while (!S.isEmpty()) {
            Node temp = S.pop();
            System.out.print(temp.data+" ");
            if (temp.right!=null) S.push(temp.right);
            if (temp.left!=null) S.push(temp.left);
        }
    }
    /*
     * 利用栈模拟递归过程实现循环先序遍历二叉树 
     * 这种方式具备扩展性,它模拟递归的过程,将左子树点不断的压入栈,直到null,然后处理栈顶节点的右子树 
     */
    public void preOrderStack_2() { //先序遍历(非递归)
        Node t = this.root; //目的是使root始终是根节点
        if (t==null)
            return ;
        Stack<Node> S = new Stack<>();
        while (t!=null || !S.isEmpty()) {
            while (t!=null) {
                System.out.print(t.data+" ");
                S.push(t);
                t = t.left;
            }
            t = S.pop();
            t = t.right;
        }
    }
    /*
     * 利用栈模拟递归过程实现循环中序遍历二叉树 
     * 思想和上面的preOrderStack_2相同,
     * 只是访问的时间是在左子树都处理完直到null的时候出栈并访问。 
     */
    public void inOrderStack() { //中序遍历
        Node t = this.root; //目的是使root始终是根节点
        if (t==null)
            return ;
        Stack<Node> S = new Stack<>();
        while (t!=null || !S.isEmpty()) {
            while (t!=null) {
                S.push(t);
                t = t.left;
            }
            t = S.pop();
            System.out.print(t.data+" ");
            t = t.right;
        }
    }
}

Test 类


import java.util.Arrays;

public class Test_BinaryTree {
    public static void main(String[] args) {
        BinaryTree bt = new BinaryTree();
        bt.add("4");
        bt.add("7");
        bt.add("6");
        bt.add("2");
        bt.add("1");
        bt.add("3");
        bt.add("5");
        System.out.println("数组递归实现先序遍历  " + Arrays.toString(bt.PretoArray()));
        System.out.println("数组递归实现中序遍历(按从小到大排序)    " + Arrays.toString(bt.toArray()));
        System.out.println("数组递归实现后序遍历  " + Arrays.toString(bt.PosttoArray()));
        System.out.println("数组非递归实现层序遍历 " + Arrays.toString(bt.LevertoArray()));
        System.out.print("非递归实现层序遍历 ");
        bt.LeverOrder();
        System.out.print("\n非递归实现先序遍历   ");
        bt.preOrderStack_1();
        System.out.print("\n非递归实现先序遍历   ");
        bt.preOrderStack_2();
        System.out.print("\n非递归实现中序遍历   ");
        bt.inOrderStack();
    }
}

结果

数组递归实现先序遍历  [4, 2, 1, 3, 7, 6, 5]
数组递归实现中序遍历(按从小到大排序)    [1, 2, 3, 4, 5, 6, 7]
数组递归实现后序遍历  [1, 3, 2, 5, 6, 7, 4]
数组非递归实现层序遍历 [4, 2, 7, 1, 3, 6, 5]
非递归实现层序遍历   4 2 7 1 3 6 5 
非递归实现先序遍历   4 2 1 3 7 6 5 
非递归实现先序遍历   4 2 1 3 7 6 5 
非递归实现中序遍历   1 2 3 4 5 6 7 

有些来源于博客https://blog.csdn.net/kerryfish/article/details/24309617

版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/qq_37131037/article/details/80561145

猜你喜欢

转载自blog.csdn.net/qq_37131037/article/details/80561145