树是一种重要的非线性数据结构。它既能像链表那样快速的插入和删除,又能像有序数组那样快速查找。二叉树是每个节点最多有两个子树的有序树。通常被称作为左子树和右子树。如果一个二叉树的每个节点的左子节点的值小于该节点,右子节点的值大于等于该节点,那么这种二叉树也称为二叉搜索树(Binary Search Tree,BST),本次学习主要关注BST。
二叉树图例:
二叉树算法的排序规则:
1、选择第一个元素作为根节点
2、之后如果元素大于根节点放在右子树,如果元素小于根节点,则放在左子树
3、最后按照中序遍历的方式进行输出,则可以看到排序的结果(中序遍历(有顺序输出):左->中->右)
基本实现代码:
public class BinaryTree {
// 根节点
private Node root;
// 添加
public void add(int data){
// 根节点为空,直接插入到根节点中,否则递归插入
if(root == null){
root = new Node(data);
} else {
root.addNode(data);
}
}
// 打印输出
public void print(){
root.printNode();
}
// 查找
public boolean find(int data){
if(root != null){
if(root.data == data){
return true;
} else {
return root.findNode(data);
}
}
return false;
}
private class Node{
// 插入的数据
private int data;
// 左子节点
private Node left;
// 右子节点
private Node right;
public Node(int data){
this.data = data;
}
public void addNode(int data){
if(this.data > data){
// 放左边 当根节点的数据大于需要插入的数据,也就是需要插入的数据小于上一节点的数据,放在节点的左边
if(this.left == null){
this.left = new Node(data);
} else {
this.left.addNode(data);
}
} else {
// 放右边
if(this.right == null){
this.right = new Node(data);
} else {
this.right.addNode(data);
}
}
}
public void printNode(){
// 中序遍历输出 左中右
if(this.left != null){
this.left.printNode();
}
System.out.print(this.data + "->");
if(this.right != null){
this.right.printNode();
}
}
public boolean findNode(int data){
if(this.data > data){
// 左边找
if(this.left != null){
if(this.left.data == data){
return true;
}else {
return this.left.findNode(data);
}
}
} else {
if(this.right != null){
if(this.right.data == data){
return true;
} else {
return this.right.findNode(data);
}
}
}
return false;
}
}
}
// 测试类
class Test{
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
// 添加
bt.add(2);
bt.add(20);
bt.add(15);
bt.add(35);
bt.add(10);
bt.add(25);
bt.add(99);
bt.add(32);
// 输出打印
bt.print();
// 查找
System.out.println(bt.find(15));
}
}
基本插入过程:
中序遍历过程:
BST效率
节点的查找需要从根节点开始一层一层往下找,树节点数和层数的关系如下表所示:
节点数 | 层数 |
---|---|
1 | 1 |
3 | 2 |
7 | 3 |
15 | 4 |
31 | 5 |
… | … |
1023 | 10 |
… | … |
32767 | 15 |
… | … |
1048575 | 20 |
… | … |
33554432 | 25 |
… | … |
1073741824 | 30 |
假设节点数为N,层数为L,那么不难看出它们的关系为:N=2^(L-1),所以L=log2(N+1),大约为log2N,大O表示法为O(logN)。