二叉树节点的表示法:
- 二叉树数组表示法
- 二叉树链表表示法
“数组表示法”属于静态内存空间配置,而“链表表示法”是利用链表结构的方式,属于动态内存空间配置。、
二叉树数组表示法
/** * 树节点的定义 */ class TreeNode { int val; TreeNode left; // 左子树节点 TreeNode right; // 右子树节点 TreeNode(int x) { val = x; } } /** * 二叉树的顺序存储结构 */ class BinaryTree { private int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9}; private static List<TreeNode> nodeList = null; /** * 树节点的定义 */ private class TreeNode { int val; TreeNode left; // 左子树节点 TreeNode right; // 右子树节点 TreeNode(int x) { left = null; right = null; val = x; } } public BinaryTree() { createBiTree(); // nodeList中第0个索引处的值即为根节点 TreeNode root = nodeList.get(0); System.out.println("先序遍历:"); preOrderTraverse(root); System.out.println(); System.out.println("中序遍历:"); inOrderTraverse(root); System.out.println(); System.out.println("后序遍历:"); postOrderTraverse(root); } /** * 构造一棵满二叉树 */ private void createBiTree() { nodeList = new LinkedList<TreeNode>(); // 将TreeNode节点加入到链表中 for (int nodeIndex=0; nodeIndex<array.length; nodeIndex++) { nodeList.add(new TreeNode(array[nodeIndex])); } // 对前lastParentIndex-1个父节点按照父节点与孩子节点的数字关系建立二叉树 for (int parentIndex=0; parentIndex<array.length/2-1; parentIndex++) { // 左孩子 nodeList.get(parentIndex).left = nodeList.get(parentIndex*2+1); // 右孩子 nodeList.get(parentIndex).right = nodeList.get(parentIndex*2+2); } // 最后一个父节点:因为最后一个父节点可能没有右孩子,所以单独拿出来处理 int lastParentIndex = array.length / 2 - 1; // 左孩子 nodeList.get(lastParentIndex).left = nodeList.get(lastParentIndex*2+1); // 右孩子,如果数组的长度为奇数才建立右孩子 if (array.length % 2 == 1) { nodeList.get(lastParentIndex).right = nodeList.get(lastParentIndex*2+2); } } /** * 先序遍历 */ public static void preOrderTraverse(TreeNode node) { if (node == null) { return; } System.out.print(node.val + " "); // 遍历左子树 preOrderTraverse(node.left); // 遍历右子树 preOrderTraverse(node.right); } /** * 中序遍历 */ public static void inOrderTraverse(TreeNode node) { if (node == null) { return; } // 遍历左子树 inOrderTraverse(node.left); System.out.print(node.val + " "); // 遍历右子树 inOrderTraverse(node.right); } /** * 后序遍历 */ public static void postOrderTraverse(TreeNode node) { if (node == null) { return; } // 遍历左子树 postOrderTraverse(node.left); // 遍历右子树 postOrderTraverse(node.right); System.out.print(node.val + " "); } }
二叉树链表表示法
/** * 二叉树的链式存储结构 * https://www.cnblogs.com/Dylansuns/p/6791852.html */ public class BinaryTree<E> { /** * 树节点的定义 */ class TreeNode { Object data; TreeNode left; // 左子树节点 TreeNode right; // 右子树节点 TreeNode() { } TreeNode(Object data) { this.data = data; } TreeNode(Object data, TreeNode left, TreeNode right) { this.data = data; this.left = left; this.right = right; } } private TreeNode root; // 以默认的构造器创建二叉树 public BinaryTree() { this.root = new TreeNode(); } // 以指定根元素创建二叉树 public BinaryTree(E data) { this.root = new TreeNode(data); } /** * 为指定节点添加子节点 */ public TreeNode addNode(TreeNode parent, E data, boolean isLeft) { if (parent == null) { throw new RuntimeException(parent + "节点为null, 无法添加子节点"); } if (isLeft && parent.left != null) { throw new RuntimeException(parent + "节点已有左子节点,无法添加左子节点"); } if (!isLeft && parent.right != null) { throw new RuntimeException(parent + "节点已有右子节点,无法添加右子节点"); } // 创建一个新节点 TreeNode newNode = new TreeNode(data); if (isLeft) { // 让父节点的left引用指向新节点 parent.left = newNode; } else { // 让父节点的right引用指向新节点 parent.right = newNode; } return newNode; } // 判断二叉树是否为空 public boolean empty() { return root.data==null; } // 返回根节点 public TreeNode root() { if (empty()) { throw new RuntimeException("树为空,无法访问根节点"); } return root; } // 返回指定节点(非叶子)的左子节点,当左子节点不存在时返回null public E leftChild(TreeNode parent) { if (parent == null) { throw new RuntimeException(parent + "节点为null,无法添加子节点"); } return parent.left == null ? null : (E) parent.left.data; } // 返回指定节点(非叶子)的右子节点,当右子节点不存在时返回null public E rightChild(TreeNode parent) { if (parent == null) { throw new RuntimeException(parent + "节点为null,无法添加子节点"); } return parent.right == null ? null : (E) parent.right.data; } // 返回二叉树的深度 public int deep() { return deep(root); } // 这是一个递归方法:每一棵子树的深度为其所有子树的最大深度 + 1 public 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; // 返回其左右子树中较大的深度 + 1 return max + 1; } } // 测试 public static void main(String[] args) { BinaryTree<String> binTree = new BinaryTree<String>("根节点"); // 依次添加节点 BinaryTree.TreeNode tn1 = binTree.addNode(binTree.root(), "第二层左节点", true); BinaryTree.TreeNode tn2 = binTree.addNode(binTree.root(), "第二层右节点", false); BinaryTree.TreeNode tn3 = binTree.addNode(tn2, "第三层左节点", true); BinaryTree.TreeNode tn4 = binTree.addNode(tn2, "第三层右节点", false); BinaryTree.TreeNode tn5 = binTree.addNode(tn3, "第四层左节点", true); System.out.println("tn2的左子节点:" + binTree.leftChild(tn2)); System.out.println("tn2的右子节点:" + binTree.rightChild(tn2)); System.out.println(binTree.deep()); } }