知识的学习在于点滴记录,坚持不懈;知识的学习要有深度和广度,不能只流于表面,坐井观天;知识要善于总结,不仅能够理解,更知道如何表达!
目录
BST二叉搜索树是面试中常考的问题,因为不涉及旋转操作和节点着色,因此比AVL和红黑树实现起来要简单很多,成为了笔试面试中写代码常见的考点。这篇文章分享一下BST树以及常见的BST树相关的笔试面试常考题目。
二分查找
对于一组有序的序列,进行搜索的时候可以采用二分搜索来提高效率,对比线性搜索的时间复杂度是O(n),对于有序序列的二分搜索时间复杂度是O( log 2 n \log_2n log2n),因此搜索效率比较高,下面提供递归以及非递归的二分搜索代码实现:
非递归版本
/**
* 二分查找的非递归实现,在有序的list集合元素中,进行二分搜索,查找val值
* @param list
* @return
*/
private static <T extends Comparable<T>>
T nonrecur_binarysearch(List<T> list, T val) {
int first = 0;
int last = list.size()-1;
int middle = 0;
T data = null;
while(first <= last){
middle = (first + last) / 2;
data = list.get(middle);
if(val.compareTo(data) < 0){
last = middle-1;
} else if(val.compareTo(data) > 0){
first = middle+1;
} else {
return data;
}
}
return null;
}
递归版本
/**
* 二分查找的递归实现,在有序的list集合元素中,进行二分搜索,查找val值
* @param list
* @param val
* @return
*/
private static <T extends Comparable<T>>
T recur_binarysearch(List<T> list, T val) {
return recur_binarysearch(list, 0, list.size()-1, val);
}
/**
* 二分查找的递归具体实现过程
* @param list
* @param i
* @param j
* @param val
* @return
*/
private static <T extends Comparable<T>>
T recur_binarysearch(List<T> list, int i, int j, T val) {
if(i > j){
return null;
}
int middle = (i + j) / 2;
T data = list.get(middle);
if(val.compareTo(data) < 0){
return recur_binarysearch(list, i, middle-1, val);
} else if(val.compareTo(data) > 0){
return recur_binarysearch(list, middle+1, j, val);
} else {
return data;
}
}
测试代码如下:
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
Random rand = new Random(50);
for(int i=0; i<20; ++i){
list.add(rand.nextInt(100));
}
Collections.sort(list);
System.out.println("排序后的元素序列:" + list);
Integer data = nonrecur_binarysearch(list, 7);
System.out.println(data);
data = recur_binarysearch(list, 28);
System.out.println(data);
}
BST二叉搜索树
上面二分搜索的过程就是BST树搜索的过程,BST树的每一个节点最多有两个孩子,而且左孩子的值 < 父节点的值 < 右孩子的值,下面定义BST树相关的类:
/**
* BST树节点的实现
* @param <T>
*/
class BSTNode<T extends Comparable<T>>{
private T data;
private BSTNode<T> left;
private BSTNode<T> right;
public BSTNode(T data) {
this(data, null, null);
}
public BSTNode(T data, BSTNode<T> left, BSTNode<T> right) {
this.data = data;
this.left = left;
this.right = right;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public BSTNode<T> getLeft() {
return left;
}
public void setLeft(BSTNode<T> left) {
this.left = left;
}
public BSTNode<T> getRight() {
return right;
}
public void setRight(BSTNode<T> right) {
this.right = right;
}
}
/**
* BST树的实现
* @param <T>
*/
class BST<T extends Comparable<T>>{
private BSTNode<T> root; // 指向BST树的根节点
public BST() {
this.root = null;
}
}
BST树常见代码题
BST树插入,删除,查询操作,递归和非递归实现
BST树的插入操作,递归和非递归代码实现:
/**
* BST树的递归插入函数接口
* @param val
*/
public void insert(T val){
this.root = insert(root, val);
}
/**
* BST树的递归插入具体实现函数
* @param root
* @param val
* @return
*/
private BSTNode<T> insert(BSTNode<T> root, T val) {
if(null == root){
return new BSTNode<>(val);
}
if(root.getData().compareTo(val) > 0){
root.setLeft(insert(root.getLeft(), val));
} else if(root.getData().compareTo<