二叉搜索树的迭代遍历方式

什么是二叉搜索树(Binary Search Tree)-BST 

二叉搜索树是一种特殊的二叉树,有许多性质

  1. 每个节点都有一个键(和一个相关联的值),并且每个节点的键都是唯一的。
  2. 对于树中的每个节点X,其左子树中的所有键都小于X的键,其右子树中的所有键都大于X的键。
  3. 每个左右子树也都是二叉搜索树。

这些性质使得二叉搜索树在进行查找、插入和删除等操作时能够提供良好的性能,平均情况下可以在O(log n)时间内完成这些操作(这里n是树中节点的数量)。

二叉搜索树的遍历方式

二叉搜索树和普通二叉树的遍历方式一致,有DFS和BFS两种,二者的实现方式也有多重。

对于普通二叉树来说:深度优先(DFS)主要分为前中后序遍历,对于广度优先(BFS)则通常借用队列实现。对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。

对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。

例如要搜索元素为3的节点,我们不需要搜索其他节点,也不需要做回溯,查找的路径已经规划好了。

对于二叉搜索树来说:

  • 中序遍历 特别有用,因为它按照排序顺序输出节点。
  • 先序遍历后序遍历 对于搜索操作没有特别的优势。


  1. 中序遍历(In-order Traversal)

    • 访问左子树
    • 访问根节点
    • 访问右子树 这种遍历方式的特点是可以按照键的顺序访问树中的所有节点。
    // 中序遍历(In-order)
    public void inorder(TreeNode root, List<Integer> list) {
        if (root == null) return;
        inorder(root.left, list);
        list.add(root.val);
        inorder(root.right, list);
    }
  1. 前序遍历(Pre-order Traversal)

    • 访问根节点
    • 访问左子树
    • 访问右子树 前序遍历在复制树结构或者输出树的结构时特别有用。
// 前序遍历(Pre-order)
    public void preorder(TreeNode root, List<Integer> list) {
        if (root == null) return;
        list.add(root.val);
        preorder(root.left, list);
        preorder(root.right, list);
    }
  1. 后序遍历(Post-order Traversal)

    • 访问左子树
    • 访问右子树
    • 访问根节点 后序遍历在删除树的节点或者计算空间占用时非常有用。
    // 后序遍历(Post-order)
    public void postorder(TreeNode root, List<Integer> list) {
        if (root == null) return;
        postorder(root.left, list);
        postorder(root.right, list);
        list.add(root.val);
    }

当我们只是简单地遍历整个树时(不是搜索特定值),并不存在一种特殊的迭代方式来利用BST的性质,因为我们不得不访问树中的所有节点。但如果我们进行中序遍历,输出的节点序列将是有序的,这是利用BST性质的一个简单例子。

  • 例如下题目,利用了二叉搜索树的优势
leetcode700.二叉搜索树中的搜索
public TreeNode searchBST(TreeNode root, int val) {
    while (root != null && root.val != val) {
        root = val < root.val ? root.left : root.right;
    }
    return root;
}

层次遍历(Level-order Traversal)

  • 从根节点开始,一层层从上到下,同一层从左到右遍历所有的节点。 层次遍历通常需要使用队列来辅助实现。
public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> result = new ArrayList<>();
    if (root == null) return result;
    
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    
    while (!queue.isEmpty()) {
        List<Integer> currentLevel = new ArrayList<>();
        int size = queue.size();
        for (int i = 0; i < size; i++) {
            TreeNode node = queue.poll();
            currentLevel.add(node.val);
            if (node.left != null) queue.offer(node.left);
            if (node.right != null) queue.offer(node.right);
        }
        result.add(currentLevel);
    }
    
    return result;
}

处理逻辑

处理逻辑的位置

  • 递归终止条件:通常是处理边界条件和递归基的地方,如检查一个节点是否为空,避免进一步的递归调用。
  • DFS中处理逻辑在中节点处:对于DFS,处理逻辑可以放在进入左子树之前、之后,或者进入右子树之后,这取决于你需要的是先序、中序还是后序遍历的效果。
  • 在BFS中处理逻辑:通常是在节点出队列时处理。

如果要在遍历过程中利用BST的性质,通常是与某个特定目标有关的问题,比如:

  • 在给定值范围内搜索所有节点。
  • 查找第k小或第k大的元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值