数据结构与算法——二叉树遍历实现

遍历Traverse:就是按照某种次序访问所有节点,且每个节点恰好访问一次。

树的遍历可以看成是人为的将非线性结构线性化


将树看成三个部分:左子树、右子树、根

遍历的方法三种:

  1. 先序DLR:根、左子树、右子树
  2. 中序LDR:左子树、根、右子树
  3. 后序LRD:左子树、右子树、根

采用了递归的思路


面试题:有一个二叉树,它的后序遍历序列为5 4 3 7 6 2 1,中序遍历的序列为4 5 1 3 2 6 7,则其先序遍历的序列是什么?

先序:1452367


实现:

先创建一棵二叉树

        Node node5 = new Node(5, null, null);
        Node node4 = new Node(4, null, node5);
        Node node3 = new Node(3, null, null);
        Node node7 = new Node(7, null, null);
        Node node6 = new Node(6, null, node7);
        Node node2 = new Node(2, node3, node6);
        Node node1 = new Node(1, node4, node2);

        BinaryTree bTree = new LinkedBinaryTree(node1);

 先序遍历

public void perOrderTraverse() {
        //输出根节点的值
        if (root != null) {
            System.out.print(root.value + " ");
            //对左子树进行先序遍历
            BinaryTree leftTree = new LinkedBinaryTree(root.leftChild);
            leftTree.perOrderTraverse();
            //对右子树进行先序遍历
            BinaryTree rightTree = new LinkedBinaryTree(root.rightChild);
            rightTree.perOrderTraverse();
        }
    }

中序遍历

    @Override
    public void inOrderTraverse(Node node) {
        if (node != null) {
            // 遍历左子树
            this.inOrderTraverse(node.leftChild);
            //输出根的值
            System.out.print(node.value + " ");
            // 遍历右子树
            this.inOrderTraverse(node.rightChild);
        }
    }

得到树的高度

思路:递归,左子树和右子树中找大的,再加上根(加1)

@Override
    public int getHeight() {
        System.out.println("二叉树的高度是");
        return this.getHeight(root);
    }

    private int getHeight(Node node) {
        if (node == null) {
            return 0;
        } else {
            // 获取左子树的高度
            int nleft = this.getHeight(node.leftChild);
            // 获取右子树的高度
            int nright = this.getHeight(node.rightChild);
            // 返回左子树,右子树较大的值并加1
            return nleft > nright ? nleft + 1 : nright + 1;
        }
    }

计算二叉树节点数量

    @Override
    public int size() {
        System.out.print("二叉树的节点数为:");
        return this.size(root);
    }

    private int size(Node node) {
        if (node == null) {
            return 0;
        } else {
            // 获取左子树的size
            int nleft = this.size(node.leftChild);
            // 获取右子树的size
            int nright = this.size(node.rightChild);
            // 返回左子树,右子树较大的值并加1
            return nleft + nright + 1;

        }
    }

在二叉树查找某个值

思路:递归 ,在某个根节点下进行查找

@Override
    public Node findKey(int value) {
        return this.findKey(value, root);
    }

    private Node findKey(Object value, Node node) {
        /*
        * 节点为空,可能是整个数的根节点,也可能是叶子节点
        */
        if (node == null) {
            return null;
        } else if (node != null && node.value == value) { // 递归接收条件,如果找到就结束递归
            return node;
        } else {
            Node node1 = this.findKey(value, node.leftChild);
            Node node2 = this.findKey(value, node.rightChild);
            if (node1 != null && node1.value == value) {
                return node1;
            } else if (node2 != null && node2.value == value) {
                return node2;
            }else {
                return null;
            }
        }
    }

按层次遍历

思路:不能用递归,借助队列

 @Override
    public void levelOrderBystack() {
        System.out.println("按照层次遍历二叉树");
        if (root == null) {
            return;
        }
        Queue<Node> queue = new LinkedList<>();
        queue.add(root);// 先把根放入队列
        while (queue.size() != 0) {
            int len = queue.size();
            for (int i = 0; i < len; i++) {
                Node temp=queue.poll();// 出队
                // 根出队后,会把根的左右孩子放入队列
                System.out.print(temp.value+" ");
                if (temp.leftChild!=null){
                    queue.add(temp.leftChild);
                }
                if (temp.rightChild!=null){
                    queue.add(temp.rightChild);
                }
            }
        }
        System.out.println();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值