1、顺序存储:采用数组来记录二叉树的全部节点。java
public class ArrayBinTree<T> { private final int DEFAULT_SIZE = 8; // 数组记录该树的全部节点 private Object[] datas; // 保存该树的深度 private int deep; private int arraySize; // 以默认深度来建立二叉树 public ArrayBinTree() { this.deep = DEFAULT_SIZE; this.arraySize = (int)Math.pow(2, deep) - 1; this.datas = new Object[arraySize]; } // 以指定深度来建立二叉树 public ArrayBinTree(int deep) { this.deep = deep; this.arraySize = (int)Math.pow(2, deep) - 1; this.datas = new Object[arraySize]; } // 以指定深度、根节点建立二叉树 public ArrayBinTree(int deep, T data) { this.deep = deep; this.arraySize = (int)Math.pow(2, deep) - 1; this.datas = new Object[arraySize]; datas[0] = data; } /** * 为指定节点添加子节点 * @param index 须要添加子节点的父节点索引 * @param data 新子节点的数据 * @param left 是否为左节点 */ public void addNode(int index, T data, boolean left) { if (datas[index] == null) { throw new RuntimeException(index + "节点为空,不能添加子节点"); } if (2 * index + 1 >= arraySize) { throw new RuntimeException("树底层的数组已满,树越界异常"); } if (left) { datas[2 * index + 1] = data; } else { datas[2 * index + 2] = data; } } // 判断二叉树是否为空 public boolean empty() { // 根据根元素来判断二叉树是否为空 return datas[0] == null; } // 返回根节点 public T root() { if (empty()) { throw new RuntimeException("树为空,没法返回根节点"); } return (T)datas[0]; } // 返回指定节点(非根节点)的父节点 public T parent(int index) { if (index == 0) { throw new RuntimeException("根节点没有父节点"); } return (T)datas[(index - 1) / 2]; } // 返回指定节点(非叶子)的左子节点,当左子节点不存在时返回null public T left(int index) { if (2 * index + 1 >= arraySize) { throw new RuntimeException(index + "节点为叶子节点,没有左子节点"); } return datas[index * 2 + 1] == null? null : (T)datas[index * 2 + 1]; } // 返回该二叉树的深度 public int deep(int index) { return deep; } // 返回指定节点的位置 public int pos(T data) { // 该循环实际上就是按广度遍从来搜索每一个节点 for (int i = 0; i < arraySize; i++) { if (datas[i] == data) { return i; } } return -1; } public String toString() { return java.util.Arrays.toString(datas); } }
2、二叉链表存储:每一个节点保留一个left、rigth域,分别指向其左、右子节点。node
public class TwoLinkBinTree<E> { public static class TreeNode { private Object data; private TreeNode left; private 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 TwoLinkBinTree() { this.root = new TreeNode(); } // 以指定根元素来建立二叉树 public TwoLinkBinTree(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(parent + "节点为空,没法添加子节点"); } if (left && parent.left != null) { throw new RuntimeException(parent + "节点已有左节点,没法添加左节点"); } if (!left && parent.right != null) { throw new RuntimeException(parent + "节点已有右节点,没法添加右节点"); } TreeNode newNode = new TreeNode(data); if (left) { parent.left = newNode; } else { parent.right = newNode; } return newNode; } // 判断二叉树是否为空 public boolean empty() { // 根据根元素来判断二叉树是否为空 return root.data == null; } // 返回根节点 public TreeNode root() { if (empty()) { throw new RuntimeException("树为空,没法返回根节点"); } return root; } // 返回指定节点(非根节点)的父节点 public E parent(TreeNode node) { // 对于二叉链表存储法,若是要访问指定节点的父节点必须遍历二叉树 return null; } // 返回指定节点(非叶子)的左子节点,当左子节点不存在时返回null public E leftChild(TreeNode parent) { if (parent == null) { throw new RuntimeException(parent + "节点为空,无左子节点"); } return parent.left == null ? null : (E)parent.left.data; } // 返回指定节点(非叶子)的右子节点。当右子节点不存在时返回null public E rightChild(TreeNode parent) { if (parent == null) { throw new RuntimeException(parent + "节点为空,无右子节点"); } return parent.right == null ? null : (E)parent.right.data; } // 二叉树的深度 public int deep() { // 获取该树的深度 deep(root); } // 递归方法:每颗子树的深度为其全部子树的最大深度 + 1 private int deep(TreeNode node) { if (node == null) { return 0; } if (node.right == null && node.left == null) { return 1; } else { int leftDeep = deep(node.left); int rightDeep = deep(node.right); int max = leftDeep > rightDeep? leftDeep : rightDeep; return max + 1; } } }
3、三叉链表存储:每一个节点保留一个left、right、parent域,分别指向其左、右子节点和父节点。数组
public class ThreeLinkBinTree<E> { public static class TreeNode { private Object data; private TreeNode parent; private TreeNode left; private TreeNode right; public TreeNode() { } public TreeNode(Object data) { this.data = data; } public TreeNode(Object data, TreeNode parent, TreeNode left, TreeNode right) { this.data = data; this.parent = parent; this.left = left; this.right = right; } } private TreeNode root; // 以默认构造器来建立二叉树 public ThreeLinkBinTree() { root = new TreeNode(); } // 以指定根元素来建立二叉树 public ThreeLinkBinTree(E data) { 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(parent + "节点为空,没法添加子节点"); } if (left && parent.left != null) { throw new RuntimeException(parent + "节点左节点不为空,没法添加左子节点"); } if (!left && parent.right != null) { throw new RuntimeException(parent + "节点右节点不为空,没法添加右子节点"); } TreeNode newNode = new TreeNode(data); if (left) { parent.left = newNode; } else { parent.right = newNode; } newNode.parent = parent; return newNode; } // 判断二叉树是否为空 public boolean empty() { // 根据根元素来判断二叉树是否为空 return root.data == null; } // 返回根节点 public TreeNode root() { if (empty()) { throw new RuntimeException("根节点为空"); } return root; } // 返回指定节点(非根节点)的父节点 public E parent(TreeNode node) { return (E)node.parent.data; } // 返回指定节点(非叶子)的左子节点。当左子节点不存在时返回null public E leftChild(TreeNode parent) { if (parent == null) { throw new RuntimeException(parent + "节点为空,无左子节点"); } return parent.left == null ? null:(E)parent.left.data; } // 返回指定节点(非叶子)的右子节点。当右子节点不存在时返回null public E rightChild(TreeNode parent) { if (parent == null) { throw new RuntimeException(parent + "节点为空,无左子节点"); } return parent.right == null ? null : (E)parent.right.data; } // 返回该二叉树的深度 public int deep() { // 获取该树的深度 deep(root); } // 递归方法:每颗子树的深度为其全部子树的最大深度 + 1 private int deep(TreeNode node) { if (node == null) { return 0; } if (node.left == null && node.right == null) { return 1; } else { int leftDeep = deep(node.left); int rightDeep = deep(node.right); int max = leftDeep > rightDeep? leftDeep : rightDeep; return max + 1; } } }
public class BinTreeTest { public static void main(String[] args) { ArrayBinTree<String> binTree = new ArrayBinTree<String>(4, "根"); binTree.addNode(0, "第二层右子节点", false); binTree.addNode(2, "第三层右子节点", false); binTree.addNode(6, "第四层右子节点", false); System.out.println("【顺序存储】二叉树:" + binTree.toString()); TwoLinkBinTree<String> binTree2 = new TwoLinkBinTree<String>("根节点"); TwoLinkBinTree.TreeNode tn1 = binTree2.addNode(binTree2.root(), "第二层左节点", true); TwoLinkBinTree.TreeNode tn2 = binTree2.addNode(binTree2.root(), "第二层右节点", false); TwoLinkBinTree.TreeNode tn3 = binTree2.addNode(tn2, "第三层左节点", true); TwoLinkBinTree.TreeNode tn4 = binTree2.addNode(tn2, "第三层右节点", false); TwoLinkBinTree.TreeNode tn5 = binTree2.addNode(tn3, "第四层左节点", true); System.out.println("tn2的左子节点:" + binTree2.leftChild(tn2)); System.out.println("tn2的右子节点:" + binTree2.rightChild(tn2)); System.out.println("【二叉链表存储】树深度:" + binTree2.deep()); ThreeLinkBinTree<String> binTree3 = new ThreeLinkBinTree<String>("根节点"); ThreeLinkBinTree.TreeNode ttn1 = binTree3.addNode(binTree3.root(), "第二层左节点", true); ThreeLinkBinTree.TreeNode ttn2 = binTree3.addNode(binTree3.root(), "第二层右节点", false); ThreeLinkBinTree.TreeNode ttn3 = binTree3.addNode(ttn2, "第三层左节点", true); ThreeLinkBinTree.TreeNode ttn4 = binTree3.addNode(ttn2, "第三层右节点", false); ThreeLinkBinTree.TreeNode ttn5 = binTree3.addNode(ttn3, "第四层左节点", true); System.out.println("tn2的左子节点:" + binTree3.leftChild(ttn2)); System.out.println("tn2的右子节点:" + binTree3.rightChild(ttn2)); System.out.println("tn2的父子节点:" + binTree3.parent(ttn2)); System.out.println("【三叉链表存储】树深度:" + binTree3.deep()); } }