public class ArrayBinaryTree {
//使用数组来存储它的所有节点
private Object[] datas;
private int DEFAULT_DEEP = 10;
//记录该树的深度
private int deep;
private int arraySize;
//默认的深度创建一个二叉树
public ArrayBinaryTree(){
this.deep = DEFAULT_DEEP;
this.arraySize = (int)Math.pow(2, deep) - 1;//等比数列求和
datas = new Object[arraySize];
}
//以指定深度创建一个二叉树
public ArrayBinaryTree(int deep){
this.deep = deep;
this.arraySize = (int)Math.pow(2, deep) - 1;
datas = new Object[arraySize];
}
//以指定深度和指定的创建一个二叉树
public ArrayBinaryTree(int deep, T root){
this.deep = deep;
this.arraySize = (int)Math.pow(2, deep) - 1;
datas = new Object[arraySize];
datas[0] = root;
}
/**
* 为指定的节点添加子节点
* @param index 需要添加的子节点的父节点的索引
* @param data 新的节点的数据
* @param left 是否为左节点
*/
public void addNode(int index, T data, boolean left){
if(datas[index] == null){
throw new RuntimeException("空节点,无法添加!");
}
if(2 * index + 1 >= arraySize){
throw new RuntimeException("底层已满,越界异常!");
}
if(left){
datas[2 * index + 1] = data;
}
else{
datas[2 * index + 2] = data;
}
}
//判断是否为空
public boolean isEmpty(){
return datas[0] == null;
}
public String toString(){
return Arrays.toString(datas);
}
}
测试代码和截图:
public class Test {
public static void main(String[] args) {
ArrayBinaryTree binTree = new ArrayBinaryTree(4, "root");
binTree.addNode( 0, "two_right", false);
binTree.addNode( 2, "three_right", false);
binTree.addNode( 6, "four_right", false);
System.out.println(binTree);
}
}
public class TwoLinkBinaryTree {
public static class TreeNode{
Object data;
TreeNode left;
TreeNode right;
public TreeNode(){
}
public TreeNode(Object data){
this.data = data;
}
public TreeNode(Object data, TreeNode left, TreeNode right){
this.data = data;
this.left = left;
this.right = right;
}
}
private TreeNode root;
//默认的构造器创建一个二叉树
public TwoLinkBinaryTree(){
this.root = new TreeNode();
}
//以指定的根元素创建一个二叉树
public TwoLinkBinaryTree(E data){
this.root = new TreeNode(data);
}
/**
* 为指定的节点添加子节点
* @param parent 父节点
* @param data 新的节点的数据
* @param left 是否为左节点
* @return 新增加的节点
*/
public TreeNode addNode(TreeNode parent, E data, boolean left){
if(parent== null){
throw new RuntimeException("空节点,无法添加!");
}
if(left && parent.left != null){
throw new RuntimeException("已有左节点,无法添加!");
}
if(!left && parent.right != null){
throw new RuntimeException("已有右节点,无法添加!");
}
TreeNode newNode = new TreeNode(data);
if(left){
parent.left = newNode;//指向这个对象 而不是指向这个值
}
else{
parent.right = newNode;
}
return newNode;
}
//返回根节点
public TreeNode root() {
if(isEmpty()){
throw new RuntimeException("空树!");
}
return root;
}
//判断是否为空
private boolean isEmpty() {
return root.data == null;
}
//返回指定节点的(非叶子)的左节点 无则返回null
public E leftChild(TreeNode parent){
if(parent == null){
throw new RuntimeException("节点空,无法添加子节点!");
}
return parent.left == null ? null : (E)parent.left.data;
}
//返回指定节点的(非叶子节点)的右节点 无则返回null
public E rightChild(TreeNode parent){
if(parent == null){
throw new RuntimeException("节点空,无法添加子节点!");
}
return parent.right == null ? null : (E)parent.right.data;
}
}
测试部分及截图(增加了几个方法,让结果更有直观性):
代码:public class Test {
public static void main(String[] args) {
// ArrayBinaryTree binTree = new ArrayBinaryTree(4, "root");
TwoLinkBinaryTree tlBinTree = new TwoLinkBinaryTree<>("root");
TwoLinkBinaryTree.TreeNode bt1 = tlBinTree.addNode(tlBinTree.root(), "two_left", true);
TwoLinkBinaryTree.TreeNode bt2 = tlBinTree.addNode(tlBinTree.root(), "two_right", false);
TwoLinkBinaryTree.TreeNode bt3 = tlBinTree.addNode(bt2, "three_right", false);
TwoLinkBinaryTree.TreeNode bt4 = tlBinTree.addNode(bt3, "four_right", false);
System.out.println("bt2的左节点:" + tlBinTree.leftChild(bt2));
System.out.println("bt2的右节点:" + tlBinTree.rightChild(bt2));
}
}
就是在二叉链表的基础上,再增加一个parent指针,指向该节点的父节点。
此时三叉链表存储的二叉树既可以方便的向下访问节点,也可以方便的向上访问节点。