二叉树的遍历

来源:互联网 发布:域名隐藏ip地址 编辑:程序博客网 时间:2024/06/05 06:05

二叉树的遍历

先序遍历

所有父节点先于左右子树的顺序,父亲 -> 左子树(递归) -> 右子树(递归)

后续遍历

所有父节点后于左右子树的顺序, 左子树(递归) -> 右子树(递归) -> 父亲

中序遍历

父节点的在左右子树的中间访问,左子树(递归)-> 父亲 -> 右子树(递归)

层序遍历

借助一个双端队列实现,比如有如下的二叉树

这里写图片描述

将根节点加入队列

不断地取出队列中第一个元素加入list, 并将当前节点的的两个孩子加入队列 ,

循环直到队列为空,则遍历结束

最终遍历结果为list, 工具双端队列queue:

list : 1 12 123 1234 12345 123456 1234567 12345678 123456789 queue: 1 23 345 4567 56789 6789 789 89 9

代码如下

package com.susq.algorithm.tree;import java.util.ArrayDeque;import java.util.ArrayList;import java.util.List;import java.util.Queue;/** * @author susq * @since 2017-12-14-14:56 */public class BinTree<E> {    private TreeNode root;    public BinTree() {        this.root = new TreeNode();    }    public BinTree(E data) {        this.root = new TreeNode(data);    }    /**     * 为指定节点添加新节点     *     * @param parent 父节点     * @param data   新的数据     * @param isLeft 是否为左孩子     * @return 新的节点     */    public TreeNode addNode(TreeNode parent, E data, boolean isLeft) {        if (parent == null) {            throw new RuntimeException("节点为null, 无法添加子节点");        }        if (isLeft && parent.left != null) {            throw new RuntimeException(parent + "已经有左子节点,无法继续添加");        }        if (!isLeft && parent.right != null) {            throw new RuntimeException(parent + "已经有右子节点,无法继续添加");        }        TreeNode newNode = new TreeNode(data);        if (isLeft) {            parent.left = newNode;        } else {            parent.right = newNode;        }        newNode.parent = parent;        return newNode;    }    public boolean empty() {        return root.data == null;    }    public TreeNode getRoot() {        if (empty()) {            throw new RuntimeException("树为空");        }        return root;    }    public E parent(TreeNode node) {        if (node == null) {            throw new RuntimeException("节点为空,没有父节点");        }        return (E) node.parent.data;    }    public E leftChild(TreeNode parent) {        if (parent == null) {            throw new RuntimeException("节点为空,没有孩子");        }        return parent.left == null ? null : (E) parent.left;    }    public E rightChild(TreeNode parent) {        if (parent == null) {            throw new RuntimeException("节点为空,没有孩子");        }        return parent.right == null ? null : (E) parent.right;    }    public int deep() {        return deep(root);    }    private int deep(TreeNode node) {        if (node == null) {            return 0;        }        if (node.left == null && node.right == null) {            return 1;        } else {            int leftDeep = deep(node.left);            int rightDeep = deep(node.right);            int max = leftDeep > rightDeep ? leftDeep : rightDeep;            return max + 1;        }    }    /**     * 实现先序遍历     *     * @return     */    public List<TreeNode> preIterator() {        return preIterator(root);    }    private List<TreeNode> preIterator(TreeNode node) {        List<TreeNode> list = new ArrayList<>();        list.add(root);        // 递归处理左子树        if (node.left != null) {            list.addAll(preIterator(node.left));        }        // 递归处理右子树        if (node.right != null) {            list.addAll(preIterator(node.right));        }        return list;    }    /**     * 实现中序遍历     *     * @return     */    public List<TreeNode> inIterator() {        return inIterator(root);    }    private List<TreeNode> inIterator(TreeNode node) {        List<TreeNode> list = new ArrayList<>();        if (node.left != null) {            list.addAll(inIterator(node.left));        }        list.add(root);        if (node.right != null) {            list.addAll(inIterator(node.right));        }        return list;    }    /**     * 实现后续遍历     *     * @return     */    public List<TreeNode> psotIterator() {        return postIterator(root);    }    private List<TreeNode> postIterator(TreeNode node) {        List<TreeNode> list = new ArrayList<>();        if (node.left != null) {            list.addAll(postIterator(node.left));        }        if (node.right != null) {            list.addAll(postIterator(node.right));        }        list.add(root);        return list;    }    /**     * 实现广度优先遍历,又称为按层遍历     * 借助一个双端队列     *     * @return     */    public List<TreeNode> breadthFirst() {        Queue<TreeNode> queue = new ArrayDeque<>(); //ArrayDeque数双端队列实现类        List<TreeNode> list = new ArrayList<>();        if (root != null) {            queue.offer(root); // offer:添加一个元素并返回true,如果队列已满,则返回false        }        // while 循环中,移除队列的第一个节点,并且将这个节点左子节点、右子节点加入队列,        // 每次取出队列中元素的时候,把它的所有孩子加入队列末尾,在二叉树中就是父节点遍历过后,把下层的节点加入队列。        while (!queue.isEmpty()) {            list.add(queue.peek()); // peek:返回队列头部的元素,如果队列为空,则返回null            TreeNode p = queue.poll(); //poll:移除并返问队列头部的元素, 如果队列为空,则返回null            if (p.left != null) {                queue.offer(p.left);            }            if (p.right != null) {                queue.offer(p.right);            }        }        return list;    }    /**     * 树的节点     */    public static class TreeNode {        Object data;        TreeNode left;        TreeNode right;        TreeNode parent;        public TreeNode() {        }        public TreeNode(Object data) {            this.data = data;        }        public TreeNode(Object data, TreeNode left, TreeNode right, TreeNode parent) {            this.data = data;            this.left = left;            this.right = right;            this.parent = parent;        }    }}
原创粉丝点击