泛型二叉树:
import java.util.ArrayList;
import java.util.List;
public class Node<T>{//泛型结点
private Node<T> leftNode = null;
private Node<T> rightNode = null;
private T value = null;
public void add(T t){
if(null == value) {
value = t;
}else {
if((int)t<=(int)value) {
if(null == leftNode) {
leftNode = new Node<T>();
}
leftNode.add(t);
}else {
if(null == rightNode) {
rightNode = new Node<T>();
}
rightNode.add(t);
}
}
}
public List<T> ergodic(){
List<T> values = new ArrayList<T>();
if(null!=leftNode)
values.addAll(leftNode.ergodic());
values.add(value);
if(null!=rightNode)
values.addAll(rightNode.ergodic());
return values;
}
public static void main(String[] args) {
int []randoms = new int[] { 67, 7, 30, 73, 10, 0, 78, 81, 10, 74 };
Node<Integer> roots = new Node<>();
for(int number:randoms)
roots.add(number);
System.out.println(roots.ergodic());
}
}
先分析一下二叉树的add方法:
- 首先判断该结点自身是否已经赋值,若为null,则赋值,add方法结束;
- 若结点自身已赋值,再比较插入数据与结点数据的大小关系,<=则进入左结点,否则进入右结点,继续后续判断;
- 进入左/右结点后,若发现左/右结点未初始化,则先new一个左/右结点;
- 最后用左/右结点再次调用add方法,递归,直至该数据被赋值给某个结点的value;
根据上述规则,可以画出如下的二叉树:
注意事项
数组中的每个数据初始add时都是从根结点出发,与根结点比较大小
递归时add方法判断大小关系就是与子结点比较,而不再是根结点。
ergodic()方法分析就有点难度了,我们继续分析:
ergodic()方法也是递归,我们知道代码都是顺序执行的,所以递归有个特性就是“先递归到底,再一层一层回溯,执行“同层代码”的剩余部分”。
在ergodic()方法中首先是针对左结点进行的,if条件是null!=leftNode,因此我们可以定位到“0”结点,“0”结点的左结点是null,因此第一个if条件失效,进行下一步,values.add(value),value是此时结点的值,此时结点是“0”结点,所以0被添加到了values列表里,{0}。当然“0”结点也没有右结点,所以就回溯到上一层。“0”结点的上一层是“7”结点,因为我们是从下一层回溯上来的,所以第一个if条件就已经过了~,直接进入values.add(value),此时7被添加到了values列表里{0,7}。然后7的右结点不等于null,因此右结点又开始调用ergodic()方法,又开始左结点递归,此时定位到最下面的10结点,这个10结点跟0结点情况一样,左结点为null,因此执行values.add(value),值为10,{0,7,10}。然后就回溯呗,此时是单叉树,所以直接回溯到7,{0,7,10,10,30}。7这一层也全部结束了,values.add(value),此时是根结点的值,{0,7,10,10,30,67}。然后执行右结点,再向左结点递归,此时我们定位到的点是73,注意不是74,因为73是最先左结点为null,所以73也进列表,{0,7,10,10,30,67,73},然后再是73的右结点,再向左结点递归,定位到74,{74,78,81},最后就是{0,7,10,10,30,67,73,74,78,81}