【数据结构】二叉树的前中后序遍历(递归与非递归)

来源:互联网 发布:vscode wordpress 编辑:程序博客网 时间:2024/06/05 06:04

1.前序遍历:根左右

若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树, 再前序遍历右子树。

这里写图片描述

前序遍历的顺序为: ABDGHCE I F 。

2.中序遍历:左根右

若树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点) ,中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树

这里写图片描述

中序遍历的顺序为: GDHBAE I CF 。

3.后序遍历:左右根

若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。

这里写图片描述

后序遍历的顺序为.: GHDBIEFCA

4.层序遍历

规则是若树为空, 则空操作返回,否则从树的第一层,也就是根结点开始访问,
从上而下逐层遍历,在同一层中, 按从左到右的颇用才结点逐个访问。

这里写图片描述

层序遍历的顺序为: ABCDEFGHL.

5.前中序遍历的代码实现(递归与非递归)

public class BinTree {    private Node root;    public BinTree() {}    //前序方式创建树(键盘输入)    public Node createBiTree() {        Scanner in = new Scanner(System.in);        char ch = in.next().charAt(0);        if (ch == '#') {            return null;        }        Node node = new Node(ch); //创建根节点        node.setLchild(createBiTree());        node.setRchild(createBiTree());        this.root = node;        return root;    }    //创建二叉树(前序遍历)定义字符串    int index = 0;    public Node init(String s) {        if (index >= s.length()) {            return null;        }        char ch = s.charAt(index++);        if (ch == '#') {            return null;        }        Node node = new Node(ch);        node.setLchild(init(s));        node.setRchild(init(s));        this.root = node;        return root;    }    //递归前序遍历    public void preOrderTraverse(Node root) {        if (root == null) {            return;        }        System.out.print(root.getData()+" ");        preOrderTraverse(root.getLchild());        preOrderTraverse(root.getRchild());    }    //递归中序遍历    public void inOrderTraverse(Node root) {        if (root == null ) {            return;        }        inOrderTraverse(root.getLchild());        System.out.print(root.getData()+" ");        inOrderTraverse(root.getRchild());    }    //递归后序遍历    public void postOrderTraverse(Node root) {        if (root == null) {            return;        }        postOrderTraverse(root.getLchild());        postOrderTraverse(root.getRchild());        System.out.print(root.getData()+" ");    }    //非递归方式前序遍历    public void preOrder(Node root) {        Stack<Node> stack = new Stack<>();        while (root != null || !stack.isEmpty()) {            while (root != null) {                System.out.print(root.getData()+" ");                stack.push(root);                root = root .getLchild();            }            if (!stack.isEmpty()) {                root = stack.pop();                root = root.getRchild();            }        }    }    //非递归中序遍历    public void inOrder(Node root) {        Stack<Node> stack = new Stack<>();        while (root != null || !stack.isEmpty()) {            while (root != null) {                stack.push(root);                root = root.getLchild();            }            if (!stack.isEmpty()) {                root = stack.pop();                System.out.print(root.getData()+" ");                root = root.getRchild();            }        }    }    //非递归后序遍历一    public void postOrder(Node root){        Node preNode = null;//记录之前遍历的右结点        Stack<Node> stack = new Stack<Node>();        while(root != null || !stack.isEmpty()){            //左子树一直入栈            while(root != null){                stack.push(root);                root = root.getLchild();            }            if (!stack.isEmpty()) {                root = stack.peek();//获得栈顶节点但不出栈                //如果右结点为空,或者右结点之前遍历过,打印根结点                if (root.getRchild() == null || root.getRchild() == preNode) {                    System.out.print(root.getData() + " ");                    root = stack.pop();                    preNode = root;                    root = null;                } else {                    root = root.getRchild();                }            }        }    }    //非递归遍历二    public void postOrder2(Node root) {        Node pre = null;        Stack<Node> stack = new Stack<>();        stack.push(root);        while (!stack.isEmpty()) {            root = stack.peek();            if ((root.getLchild() == null && root.getRchild() == null) ||                    ((pre != null)&&(root.getRchild() == pre || root.getLchild() == pre))) {                System.out.print(root.getData()+" ");                pre = stack.pop();            }else {                if (root.getRchild() != null) {                    stack.push(root.getRchild());                }                if (root.getLchild() != null) {                    stack.push(root.getLchild());                }            }        }    }    private class Node {        private Node lchild;        private Node rchild;        private char data;        public Node(Node lchild, char data, Node rchild) {            this.lchild = lchild;            this.data = data;            this.rchild = rchild;        }        public Node(char data) {            this(null,data,null);//            this.lchild = null;//            this.rchild = null;//            this.data = data;        }        public char getData() {            return this.data;        }        public Node getLchild() {            return this.lchild;        }        public Node getRchild() {            return this.rchild;        }        public void setData(char data) {            this.data = data;        }        public void setLchild(Node node) {            this.lchild = node;        }        public void setRchild(Node node) {            this.rchild = node;        }    }    public static void main(String[] args) {        BinTree binTree = new BinTree();        Node root = binTree.init("ABD###C#EF###");        System.out.println("递归遍历:");        binTree.preOrderTraverse(root);        System.out.println();        binTree.inOrderTraverse(root);        System.out.println();        binTree.postOrderTraverse(root);        System.out.println("\n"+"非递归遍历:");        binTree.preOrder(root);        System.out.println();        binTree.inOrder(root);        System.out.println();        binTree.postOrder2(root);    }}



本人才疏学浅,若有错,请指出
谢谢!

阅读全文
0 0
原创粉丝点击