📜  数据结构 |平衡二叉搜索树 |问题 13(1)

📅  最后修改于: 2023-12-03 15:10:19.768000             🧑  作者: Mango

数据结构 | 平衡二叉搜索树 | 问题 13

简介

平衡二叉搜索树(Balanced Binary Search Tree,简称BBST)是一种自平衡的二叉搜索树,即将树的高度保持在较小的范围内,从而保证查询、插入、删除操作的时间复杂度在 O(log n) 级别,而不是平衡性较低的二叉搜索树的 O(n)。常见的平衡二叉搜索树有红黑树、AVL树等。

本文将重点介绍平衡二叉搜索树问题的第13个问题:如何在平衡二叉搜索树中查找第k小的元素。

问题描述

给定一个平衡二叉搜索树和一个整数 k,编写一个函数来查找树中第 k 小的元素。

解法
递归中序遍历

由于平衡二叉搜索树中序遍历的结果是一个有序数组,我们可以对平衡二叉搜索树进行中序遍历,并将遍历结果存储在一个数组中,然后返回数组中的第 k-1 个元素。

class Solution {
    public int kthSmallest(TreeNode root, int k) {
        List<Integer> list = new ArrayList<>();
        inorder(root, list);
        return list.get(k - 1);
    }

    private void inorder(TreeNode root, List<Integer> list) {
        if (root == null) {
            return;
        }
        inorder(root.left, list);
        list.add(root.val);
        inorder(root.right, list);
    }
}

该解法时间复杂度为 O(n)。

迭代中序遍历

上述解法使用了递归的方式进行中序遍历,我们也可以通过迭代的方式进行中序遍历,并使用栈来存储中间结果。

class Solution {
    public int kthSmallest(TreeNode root, int k) {
        Stack<TreeNode> stack = new Stack<>();
        while (true) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            if (--k == 0) {
                return root.val;
            }
            root = root.right;
        }
    }
}

该解法时间复杂度为 O(n),空间复杂度为 O(h),其中 h 为树的高度。

优先队列

我们可以使用一个优先队列来保存平衡二叉搜索树中的前 k 小元素,并保持其大小不超过 k。遍历完整棵树后,队列中的根元素就是第 k 小元素。

class Solution {
    public int kthSmallest(TreeNode root, int k) {
        PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
        traverse(root, pq, k);
        return pq.peek();
    }

    private void traverse(TreeNode root, PriorityQueue<Integer> pq, int k) {
        if (root == null) {
            return;
        }
        pq.offer(root.val);
        if (pq.size() > k) {
            pq.poll();
        }
        traverse(root.left, pq, k);
        traverse(root.right, pq, k);
    }
}

该解法时间复杂度为 O(nlogk),空间复杂度为 O(k)。

总结

本文介绍了平衡二叉搜索树问题的第13个问题:如何在平衡二叉搜索树中查找第k小的元素。我们可以通过中序遍历、优先队列等方式来解决这个问题。其中,中序遍历的时间复杂度为 O(n),空间复杂度为 O(n);迭代中序遍历的时间复杂度为 O(n),空间复杂度为 O(h);优先队列的时间复杂度为 O(nlogk),空间复杂度为 O(k)。