树的算法

树的定义

    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }

遍历

1.中序遍历

1.1 定义:先遍历左节点,然后根节点,然后右节点
1.2 实现:可以借助一个stack,先遍历到末尾找到最后的左子节点,然后pop出来取值,遍历右节点

    public void inordertraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();

        while (!stack.isEmpty() || root != null) {
            while (root != null) {
                stack.add(root);
                root = root.left;
            }
            root = stack.pop();
            System.out.println(root.val);
            root = root.right;
        }
    }

2.先序遍历

2.1 定义:先遍历root,然后左节点,然后右节点,== 广度优先
2.2 实现:借助队列实现,入队出队入队出队

    public void preorderTraversal(TreeNode root) {
        LinkedList<TreeNode> linkedList = new LinkedList<>();

        while (!linkedList.isEmpty() || root != null) {
            if (!linkedList.contains(root)) {
                linkedList.add(root);
            }
            if (root.left !=null) linkedList.add(root.left);
            if (root.right !=null) linkedList.add(root.right);
            root = linkedList.pop();
            System.out.println(root.val);
            if (linkedList.isEmpty()) return;
            root = linkedList.getFirst();
        }
    }

3.后序遍历

3.1 定义:先左节点,然后右,最后root
3.2 实现:
在这里插入图片描述

    public void postordeTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        Map<TreeNode, Integer> map = new HashMap<>();

        while (!stack.isEmpty() || root != null) {
            if (root != null) {
                stack.push(root);
                map.put(root, 1);
                root = root.left;

            } else {
                root = stack.peek();
                if (map.get(root) == 2) {
                    stack.pop();
                    System.out.println(root.val);
                    root = null;
                } else {
                    map.put(root, 2);
                    root = root.right;
                }
            }
        }
    }

BST(二叉搜索树)

1.定义

左子树节点都比右子树节点的值小

2.构造

1.用中序遍历的去遍历一个BST,可以得到一个有序数列;
2.有一段序列,用不同遍历方法得到的遍历结果,不一定能得到一个唯一的序列
比如:Pre + In != Only ANS
Pre + Post = Only ANS
IN + Post = Only ANS
3.单独给一个有序数列,相当于给一个BST的中序遍历结果,不能得到唯一的BST

3.用有序数列来构造BST

思路:
递归的实现,选序列中间的节点作为root,把root的左边进行递归,root的右边进行递归。
递归的出口是每次选择子序列的中间节点作为子树的root,当left 和right交叉时,返回null。
代码:

public class SortedArrayToBST {
    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }
    int[] nums;
    public TreeNode helper(int left, int right) {
        if (left > right) {
            return null;
        }
        int p = (left + right) / 2;

        TreeNode root = new TreeNode(nums[p]);
        root.left  = helper(left, p - 1);
        root.right = helper(p + 1, right);
        return root;
    }

    public TreeNode sortedArrayToBST(int[] nums) {
        this.nums = nums;
        return helper(0, nums.length - 1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值