- 观看数据结构简单的小总结,方便想起来咋回事
- 这里写了二叉查找树的简易实现中的各个方法的简易解释
- 树的定义:定义树的一种自然的方式是递归的方式。一棵树是一些节点的集合。这个集合可能是空集;若不是空集,则树由 根节点(root)和 0个或多个非空的(子)树T1,T2...组成
//二叉树 要求所有的项都能够排序,
//所以这里的 T 需要实现Comparable 接口,要可以进行 compareTo 比较大小的
public class MyBinaryTree<T extends Comparable<? super T>> {
//这里的节点 与 链表类中的一样
private static class BinaryNode<T> {
T data;
BinaryNode<T> left;
BinaryNode<T> right;
public BinaryNode(T data) {
this(data, null, null);
}
public BinaryNode(T data, BinaryNode<T> left, BinaryNode<T> right) {
this.data = data;
this.left = left;
this.right = right;
}
}
//这是 根节点
private BinaryNode<T> root;
public MyBinaryTree() {
root = null;
}
public void makeEmpty(){
root = null;
}
public boolean isEmpty(){
return root == null;
}
/**
* 根据对比来获取是否是有t对应的数据在树中
*/
public boolean contain(T t) {
return contains(t, root);
}
private boolean contains(T t, BinaryNode<T> node) {
if (node == null) return false;
int compareTo = t.compareTo(node.data);
//比较后,小于了,就递归的向当前node的左边(node.left) 继续寻找 t
//结束条件是node==null ->false 或者 compareTo==0 ->true
if (compareTo < 0) {
return contains(t, node.left);
} else if (compareTo > 0) {
return contains(t, node.right);
} else {
return true;
}
}
/**
* 找到最小的 , 就是树的的最左边的节点
*/
public T findMin() {
if (root == null)
throw new NullPointerException();
return findMin(root).data;
}
private BinaryNode<T> findMin(BinaryNode<T> node) {
if (node == null) {
return null;
}
if (node.left == null) {
return node;
}
return findMin(node.left); //这里递归的寻找
}
/**
* 找到最大的 , 就是树的的最右边的节点 这里用的是循环, 不是递归!
*/
public T findMax() {
if (root == null)
throw new NullPointerException();
return findMax(root).data;
}
private BinaryNode<T> findMax(BinaryNode<T> node) {
if (node == null) {
return null;
}
while (node.right != null) {
node = node.right;
}
return node;
}
/**
* 插入数据的时候,需要以root为开始,进行遍历对比插入,
* 当第一次插入的时候 root == null , 所以第一次插入需要改变root的变化
* 后面的就是需要 根据比较 node.data 来进行递归的将数据放到指定的位置
* 结束是在node == null 的时候 将数据放到左右都为null的node中
*/
public void insert(T t) {
root = insert(t, root);
}
private BinaryNode<T> insert(T t, BinaryNode<T> node) {
if (node == null) {
return new BinaryNode<T>(t, null, null);
}
int compareTo = t.compareTo(node.data);
if (compareTo < 0) {
node.left = insert(t, node.left);
} else if (compareTo > 0) {
node.right = insert(t, node.right);
} else {
//todo 相等了放到一个集合里,或者更新data。。。
}
return node;
}
public void remove(T t) {
root = remove(t, root);
}
private BinaryNode<T> remove(T t, BinaryNode<T> node) {
if (node == null) {
return node;//todo
}
int compareTo = t.compareTo(node.data);
if (compareTo < 0) {
//往左边继续找
node.left = remove(t, node.left);
} else if (compareTo > 0) {
//往右边继续找
node.right = remove(t, node.right);
} else if (node.left != null && node.right != null) {
//这里找到了,
//如果左右都不为空的话,将当前node的数据 改成 当前node下面的最小的node的数据
node.data = findMin(node).data;
//然后当前的node的右链表 = 把刚得到的 node.data 数据 从 node.right 开始查找进行删除
node.right = remove(node.data, node.right);
} else {
//这里也找到了, 但是左右链表 中 有一个为空
//如果左链 不为空,就将当前的node赋值为左链表 , 反之, 右链表。 也就是吧当前的 node进行了删除
node = (node.left != null) ? node.left : node.right;
}
return node;
}
/**
* 遍历树
*/
public void printTree() {
if (root == null) {
System.out.println("tree is empty ");
} else {
printTree(root);
}
}
private void printTree(BinaryNode<T> node) {
if (node != null) {
printTree(node.left);
System.out.print(node.data + " , ");
printTree(node.right);
}
}
/**
* 获取树的高度,也可叫做 深度 。
*/
public int height() {
return height(root);
}
private int height(BinaryNode<T> node) {
if (node == null)
return -1;
else
return 1 + Math.max( height(node.left), height(node.right) );
}