给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。
说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。
示例 1:
输入: root = [3,1,4,null,2], k = 1
3
/
1 4
2
输出: 1
示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/
3 6
/
2 4
/
1
输出: 3
进阶:
如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
原理:
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(log(n))
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private List <int>contain=new List <int >();
public int KthSmallest(TreeNode root, int k)
{
Ergodic(root);
return contain[k-1];
}
public void Ergodic(TreeNode node)
{
if (node == null)
return ;
Ergodic(node.left);
contain.Add(node.val);
Ergodic(node.right);
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private int result;
private int i=0;
private int k;
public int KthSmallest(TreeNode root, int k)
{
this.k=k;
Ergodic(root);
return result;
}
public void Ergodic(TreeNode node )
{
if (node == null)
return ;
Ergodic(node.left);
if(k==++i)
result=node.val;
Ergodic(node.right);
}
}
前中后序遍历
//二分搜索树的前序遍历(前序遍历:根结点 ---> 左子树 ---> 右子树)
public void preOrder() {
preOrder(root);
}
//前序遍历以node为根的二分搜索树,递归算法
private void preOrder(Node node) {
if (node == null) {
return;
}
System.out.println(node.e);
preOrder(node.left);
preOrder(node.right);
}
//二分搜索树的中序遍历(中序遍历:左子树---> 根结点 ---> 右子树)
public void inOrder() {
inOrder(root);
}
//中序遍历以node为根的二分搜索树,递归算法
private void inOrder(Node node) {
if (node == null) {
return;
}
inOrder(node.left);
System.out.println(node.e);
inOrder(node.right);
}
//二分搜索树的后序遍历(后序遍历:左子树 ---> 右子树 ---> 根结点)
public void postOrder() {
postOrder(root);
}
//后序遍历以node为根的二分搜索树,递归算法
private void postOrder(Node node) {
if (node == null) {
return;
}
postOrder(node.left);
postOrder(node.right);
System.out.println(node.e);
}
//层次遍历--(基于队列实现)
public void levelOrder() {
Queue<Node> q = new LinkedList<>();
q.add(root);
while (!q.isEmpty()) {
Node cur = q.remove();
System.out.println(cur.e);
if (cur.left != null) {
q.add(cur.left);
}
if (cur.right!=null){
q.add(cur.right);
}
}
}