定义
树(Tree)是n(n≥0)个结点的有限集,n=0时称为空树,在任意一颗非空树中:
(1)有且仅有一个特定的称为根的结点;
(2)当n>1时,其余结点可分为m(m≥0)个互不相交的有限集T1、T2…Tn,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。
特点
- 每个节点有零个或多个子节点;
- 没有父节点的节点称为根节点;
- 每一个非根节点有且只有一个父节点;
- 除了根节点外,每个子节点可以分为多个不相交的子树;
属性:
- 孩子:结点的子树的根称为结点的孩子,对应该结点称为孩子的双亲。
- 度:结点拥有子树的数量称为度。树的度是各结点度的最大值。
- 深度:结点的层次从根开始,根为第一层,根的孩子为第二层,一次类推。树中结点的最大层次称为树的深度。
扩展:
- 二叉树
- 斜树
- 满二叉树
- 完全二叉树
- 平衡二叉树
- 红黑树
- B+树
总结:
树在实际应用中广泛用到,例如oracle的数据库默认索引结构用的是B-Tree,还有在JDK1.8中HashMap的底层源码中用到了红黑树。这些二叉树的功能强大,但算法上比较复杂,想学习的话还是需要花时间深入了解。
java实现树
public class BinarySearchTree {
private Node tree;
public Node find(int data) {
Node p = tree;
while (p != null) {
if (data < p.data) p = p.left;
else if (data > p.data) p = p.right;
else return p;
}
return null;
}
public void insert(int data) {
if (tree == null) {
tree = new Node(data);
return;
}
Node p = tree;
while (p != null) {
if (data > p.data) {
if (p.right == null) {
p.right = new Node(data);
return;
}
p = p.right;
} else { // data < p.data
if (p.left == null) {
p.left = new Node(data);
return;
}
p = p.left;
}
}
}
public void delete(int data) {
Node p = tree; // p指向要删除的节点,初始化指向根节点
Node pp = null; // pp记录的是p的父节点
while (p != null && p.data != data) {
pp = p;
if (data > p.data) p = p.right;
else p = p.left;
}
if (p == null) return; // 没有找到
// 要删除的节点有两个子节点
if (p.left != null && p.right != null) { // 查找右子树中最小节点
Node minP = p.right;
Node minPP = p; // minPP表示minP的父节点
while (minP.left != null) {
minPP = minP;
minP = minP.left;
}
p.data = minP.data; // 将minP的数据替换到p中
p = minP; // 下面就变成了删除minP了
pp = minPP;
}
// 删除节点是叶子节点或者仅有一个子节点
Node child; // p的子节点
if (p.left != null) child = p.left;
else if (p.right != null) child = p.right;
else child = null;
if (pp == null) tree = child; // 删除的是根节点
else if (pp.left == p) pp.left = child;
else pp.right = child;
}
public Node findMin() {
if (tree == null) return null;
Node p = tree;
while (p.left != null) {
p = p.left;
}
return p;
}
public Node findMax() {
if (tree == null) return null;
Node p = tree;
while (p.right != null) {
p = p.right;
}
return p;
}
public static class Node {
private int data;
private Node left;
private Node right;
public Node(int data) {
this.data = data;
}
}
}