树结构的概念和特点
概念:
树是一种非线性的数据结构,由n(n≥0)个有限节点组成一个具有层次关系的集合。它有一个特殊的节点,称为根节点(Root),其余节点分成m(m≥0)个互不相交的集合T1, T2, ..., Tm,其中每一个集合Ti(1≤i≤m)又是一棵结构与树类似的子树。每棵子树的根节点有且只有一个前驱,可以有0个或多个后继。
特点:
- 每个节点有零个或多个子节点。
- 没有父节点的节点称为根节点。
- 每一个非根节点有且只有一个父节点。
- 除了根节点外,每个子节点可以分为多个不相交的子树。
二叉树的概念和特点
概念:
二叉树是每个节点最多有两个子节点的树结构,通常子节点被称作“左子节点”和“右子节点”。
特点:
- 每个节点最多有两个子节点,通常称为左子节点和右子节点。
- 左子节点的值小于其父节点的值,右子节点的值大于其父节点的值(这是二叉搜索树的特点,但普通二叉树没有这个要求)。
- 二叉树的子树也是二叉树。
Java代码实现二叉树基本操作
class TreeNode { | |
int value; | |
TreeNode left; | |
TreeNode right; | |
TreeNode(int value) { | |
this.value = value; | |
this.left = null; | |
this.right = null; | |
} | |
} | |
public class BinaryTree { | |
private TreeNode root; | |
// 初始化二叉树 | |
public BinaryTree() { | |
this.root = null; | |
} | |
// 添加节点 | |
public void addNode(int value) { | |
root = addRecursive(root, value); | |
} | |
private TreeNode addRecursive(TreeNode current, int value) { | |
if (current == null) { | |
return new TreeNode(value); | |
} | |
if (value < current.value) { | |
current.left = addRecursive(current.left, value); | |
} else { | |
current.right = addRecursive(current.right, value); | |
} | |
return current; | |
} | |
// 查找节点 | |
public TreeNode findNode(int value) { | |
return findRecursive(root, value); | |
} | |
private TreeNode findRecursive(TreeNode current, int value) { | |
if (current == null) { | |
return null; | |
} | |
if (current.value == value) { | |
return current; | |
} | |
TreeNode result = findRecursive(current.left, value); | |
if (result == null) { | |
result = findRecursive(current.right, value); | |
} | |
return result; | |
} | |
// 获取左子树 | |
public TreeNode getLeftSubtree(TreeNode node) { | |
return node != null ? node.left : null; | |
} | |
// 获取右子树 | |
public TreeNode getRightSubtree(TreeNode node) { | |
return node != null ? node.right : null; | |
} | |
// 判断空树 | |
public boolean isEmpty() { | |
return root == null; | |
} | |
// 计算二叉树深度 | |
public int calculateDepth() { | |
return calculateDepthRecursive(root); | |
} | |
private int calculateDepthRecursive(TreeNode node) { | |
if (node == null) { | |
return 0; | |
} | |
int leftDepth = calculateDepthRecursive(node.left); | |
int rightDepth = calculateDepthRecursive(node.right); | |
return Math.max(leftDepth, rightDepth) + 1; | |
} | |
// 清空二叉树 | |
public void clear() { | |
root = null; | |
} | |
// 显示节点数据(前序遍历示例) | |
public void display(TreeNode node) { | |
if (node != null) { | |
System.out.print(node.value + " "); | |
display(node.left); | |
display(node.right); | |
} | |
} | |
// 遍历二叉树(前序遍历) | |
public void preOrderTraversal() { | |
display(root); | |
} | |
// 遍历二叉树(中序遍历,需要额外方法) | |
public void inOrderTraversal() { | |
inOrderDisplay(root); | |
} | |
private void inOrderDisplay(TreeNode node) { | |
if (node != null) { | |
inOrderDisplay(node.left); | |
System.out.print(node.value + " "); | |
inOrderDisplay(node.right); | |
} | |
} | |
// 遍历二叉树(后序遍历,需要额外方法) | |
public void postOrderTraversal() { | |
postOrderDisplay(root); | |
} | |
private void postOrderDisplay(TreeNode node) { | |
if (node != null) { | |
postOrderDisplay(node.left); | |
postOrderDisplay(node.right); | |
System.out.print(node.value + " "); | |
} | |
} | |
使用:
public static void main(String[] args) { | |
BinaryTree tree = new BinaryTree(); | |
// 添加节点 | |
tree.addNode(5); | |
tree.addNode(3); | |
tree.addNode(7); | |
tree.addNode(2); | |
tree.addNode(4); | |
tree.addNode(6); | |
tree.addNode(8); | |
// 显示二叉树的前序遍历 | |
System.out.print("Pre-order traversal: "); | |
tree.preOrderTraversal(); | |
System.out.println(); | |
// 显示二叉树的中序遍历 | |
System.out.print("In-order traversal: "); | |
tree.inOrderTraversal(); | |
System.out.println(); | |
// 显示二叉树的后序遍历 | |
System.out.print("Post-order traversal: "); | |
tree.postOrderTraversal(); | |
System.out.println(); | |
// 查找节点 | |
TreeNode foundNode = tree.findNode(4); | |
if (foundNode != null) { | |
System.out.println("Found node with value: " + foundNode.value); | |
} else { | |
System.out.println("Node not found."); | |
} | |
// 判断是否为空树 | |
System.out.println("Is the tree empty? " + tree.isEmpty()); | |
// 计算二叉树深度 | |
System.out.println("Depth of the tree: " + tree.calculateDepth()); | |
// 清空二叉树 | |
tree.clear(); | |
// 再次判断是否为空树 | |
System.out.println("Is the tree empty after clearing? " + tree.isEmpty()); | |
} |
在这个 main
方法中,我们创建了一个 BinaryTree
对象,并向其中添加了几个节点。然后,我们使用 preOrderTraversal
、inOrderTraversal
和 postOrderTraversal
方法来显示二叉树的前序、中序和后序遍历。接下来,我们使用 findNode
方法来查找一个节点,并使用 isEmpty
方法来检查树是否为空。我们还使用 calculateDepth
方法来计算二叉树的深度,并使用 clear
方法来清空树。最后,我们再次使用 isEmpty
方法来确认树已被清空。