二叉树(Binary Tree) 是每个结点最多有两个子树(左子树、右子树)的树结构,左右子树有明确次序,不能随意颠倒。二叉树不是树的特殊情况,而是另一种树形结构。
二叉树的定义: 二叉树是 n(n ≥ 0)个结点的有限集合,要么是空集(空二叉树),要么由一个根结点及两棵互不相交的、分别称为左子树和右子树的二叉树组成。该定义是递归的。
二叉树的性质:
n0 = n2 + 1。(证明:总分支数 = n0 + 2·n2 = 结点总数 − 1 = (n0+n1+n2) − 1,整理得 n0 = n2 + 1。)特殊形态:
存储结构:
data、left、right 三个字段。适合任意二叉树,是实际中最常用的方式。适用场景:表达式树、二叉排序树、堆、哈夫曼树、搜索与排序(如平衡二叉树)、文件系统目录等。
| 操作 | 说明 |
|---|---|
Create 创建 |
按先序序列(含空结点标记)创建二叉树 |
PreOrder 前序遍历 |
根 → 左 → 右 |
InOrder 中序遍历 |
左 → 根 → 右 |
PostOrder 后序遍历 |
左 → 右 → 根 |
LevelOrder 层序遍历 |
从上到下、从左到右(用队列) |
| 求结点数 / 叶子数 | 统计结点或叶子数量 |
| 求高度 / 深度 | 计算树的高度(根到最远叶子的边数/层数) |
非递归遍历思想:用栈模拟递归过程。前/中序遍历用一个栈保存待访问的结点;后序遍历需额外标记或双栈;层序遍历用队列实现。所有递归算法都可转化为用栈实现的非递归版本,本质相同。
| 操作 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
| 创建 | O(n) | O(h) | 递归建树,访问每个结点一次 |
| 前/中/后序遍历 | O(n) | O(h) | 每个结点访问一次 |
| 层序遍历 | O(n) | O(w) | w 为最大宽度,最坏 O(n) |
| 求高度/结点数/叶子数 | O(n) | O(h) | 递归遍历整棵树 |
其中 h 为树的高度(递归栈深度)。
为什么: 前/中/后序遍历每个结点恰好访问一次,共 n 个结点,故时间 O(n)。递归实现时系统递归栈的最大深度等于树的高度 h,故空间 O(h);最坏情况(斜树)下 h = n,空间退化为 O(n)。层序遍历用队列,队中最多同时容纳一层结点,宽度最坏为 O(n)。
以下四种语言均用链式存储实现二叉树,包含:递归创建、前序/中序/后序递归遍历、层序遍历(队列)、求高度/结点数/叶子数,并演示同一棵二叉树的结果。
演示的二叉树(先序含空标记创建):
A
/ \
B C
/ \ \
D E F
先序含空序列:A B D # # E # # C # F # #(# 表示空结点)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef char ElemType;
// 二叉树结点(链式存储)
typedef struct BTNode {
ElemType data;
struct BTNode *left;
struct BTNode *right;
} BTNode;
// 按先序序列创建二叉树,读到 # 表示空结点
BTNode *CreateTree(char **p) {
char ch = **p;
(*p)++; // 指针后移
if (ch == '#') return NULL;
BTNode *node = (BTNode *)malloc(sizeof(BTNode));
node->data = ch;
node->left = CreateTree(p);
node->right = CreateTree(p);
return node;
}
// 前序遍历:根左右
void PreOrder(BTNode *root) {
if (root == NULL) return;
printf("%c ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
// 中序遍历:左根右
void InOrder(BTNode *root) {
if (root == NULL) return;
InOrder(root->left);
printf("%c ", root->data);
InOrder(root->right);
}
// 后序遍历:左右根
void PostOrder(BTNode *root) {
if (root == NULL) return;
PostOrder(root->left);
PostOrder(root->right);
printf("%c ", root->data);
}
// 层序遍历:用队列
void LevelOrder(BTNode *root) {
if (root == NULL) return;
BTNode *queue[100]; // 简单队列
int front = 0, rear = 0;
queue[rear++] = root;
while (front < rear) {
BTNode *node = queue[front++];
printf("%c ", node->data);
if (node->left) queue[rear++] = node->left;
if (node->right) queue[rear++] = node->right;
}
}
// 求高度
int Height(BTNode *root) {
if (root == NULL) return 0;
int l = Height(root->left);
int r = Height(root->right);
return (l > r ? l : r) + 1;
}
// 求结点数
int CountNodes(BTNode *root) {
if (root == NULL) return 0;
return CountNodes(root->left) + CountNodes(root->right) + 1;
}
// 求叶子数
int CountLeaves(BTNode *root) {
if (root == NULL) return 0;
if (root->left == NULL && root->right == NULL) return 1;
return CountLeaves(root->left) + CountLeaves(root->right);
}
int main() {
char seq[] = "ABD##E##C#F##";
char *p = seq;
BTNode *root = CreateTree(&p);
printf("前序: "); PreOrder(root); printf("\n"); // A B D E C F
printf("中序: "); InOrder(root); printf("\n"); // D B E A C F
printf("后序: "); PostOrder(root); printf("\n"); // D E B F C A
printf("层序: "); LevelOrder(root); printf("\n"); // A B C D E F
printf("高度: %d\n", Height(root)); // 3
printf("结点数: %d\n", CountNodes(root)); // 6
printf("叶子数: %d\n", CountLeaves(root)); // 3
return 0;
}
#include <iostream>
#include <queue>
using namespace std;
typedef char ElemType;
// 二叉树结点
struct BTNode {
ElemType data;
BTNode *left;
BTNode *right;
BTNode(ElemType d) : data(d), left(nullptr), right(nullptr) {}
};
// 按先序序列创建二叉树,# 表示空结点
BTNode *CreateTree(const char *&p) {
if (*p == '\0') return nullptr;
char ch = *p++;
if (ch == '#') return nullptr;
BTNode *node = new BTNode(ch);
node->left = CreateTree(p);
node->right = CreateTree(p);
return node;
}
// 前序
void PreOrder(BTNode *root) {
if (!root) return;
cout << root->data << " ";
PreOrder(root->left);
PreOrder(root->right);
}
// 中序
void InOrder(BTNode *root) {
if (!root) return;
InOrder(root->left);
cout << root->data << " ";
InOrder(root->right);
}
// 后序
void PostOrder(BTNode *root) {
if (!root) return;
PostOrder(root->left);
PostOrder(root->right);
cout << root->data << " ";
}
// 层序:用 queue
void LevelOrder(BTNode *root) {
if (!root) return;
queue<BTNode *> q;
q.push(root);
while (!q.empty()) {
BTNode *node = q.front();
q.pop();
cout << node->data << " ";
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
}
int Height(BTNode *root) {
if (!root) return 0;
return max(Height(root->left), Height(root->right)) + 1;
}
int CountNodes(BTNode *root) {
if (!root) return 0;
return CountNodes(root->left) + CountNodes(root->right) + 1;
}
int CountLeaves(BTNode *root) {
if (!root) return 0;
if (!root->left && !root->right) return 1;
return CountLeaves(root->left) + CountLeaves(root->right);
}
int main() {
const char *seq = "ABD##E##C#F##";
BTNode *root = CreateTree(seq);
cout << "前序: "; PreOrder(root); cout << endl; // A B D E C F
cout << "中序: "; InOrder(root); cout << endl; // D B E A C F
cout << "后序: "; PostOrder(root); cout << endl; // D E B F C A
cout << "层序: "; LevelOrder(root); cout << endl; // A B C D E F
cout << "高度: " << Height(root) << endl; // 3
cout << "结点数: " << CountNodes(root) << endl; // 6
cout << "叶子数: " << CountLeaves(root) << endl; // 3
return 0;
}
import java.util.LinkedList;
import java.util.Queue;
public class BinaryTree {
// 结点类
static class BTNode {
char data;
BTNode left;
BTNode right;
BTNode(char d) { data = d; }
}
private static int idx = 0; // 全局索引,用于创建
// 按先序序列创建,# 表示空结点
public static BTNode createTree(String seq) {
if (idx >= seq.length()) return null;
char ch = seq.charAt(idx++);
if (ch == '#') return null;
BTNode node = new BTNode(ch);
node.left = createTree(seq);
node.right = createTree(seq);
return node;
}
public static void preOrder(BTNode root) {
if (root == null) return;
System.out.print(root.data + " ");
preOrder(root.left);
preOrder(root.right);
}
public static void inOrder(BTNode root) {
if (root == null) return;
inOrder(root.left);
System.out.print(root.data + " ");
inOrder(root.right);
}
public static void postOrder(BTNode root) {
if (root == null) return;
postOrder(root.left);
postOrder(root.right);
System.out.print(root.data + " ");
}
// 层序:用队列
public static void levelOrder(BTNode root) {
if (root == null) return;
Queue<BTNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
BTNode node = q.poll();
System.out.print(node.data + " ");
if (node.left != null) q.offer(node.left);
if (node.right != null) q.offer(node.right);
}
}
public static int height(BTNode root) {
if (root == null) return 0;
return Math.max(height(root.left), height(root.right)) + 1;
}
public static int countNodes(BTNode root) {
if (root == null) return 0;
return countNodes(root.left) + countNodes(root.right) + 1;
}
public static int countLeaves(BTNode root) {
if (root == null) return 0;
if (root.left == null && root.right == null) return 1;
return countLeaves(root.left) + countLeaves(root.right);
}
public static void main(String[] args) {
idx = 0; // 重置索引
BTNode root = createTree("ABD##E##C#F##");
System.out.print("前序: "); preOrder(root); System.out.println(); // A B D E C F
System.out.print("中序: "); inOrder(root); System.out.println(); // D B E A C F
System.out.print("后序: "); postOrder(root); System.out.println(); // D E B F C A
System.out.print("层序: "); levelOrder(root); System.out.println(); // A B C D E F
System.out.println("高度: " + height(root)); // 3
System.out.println("结点数: " + countNodes(root)); // 6
System.out.println("叶子数: " + countLeaves(root)); // 3
}
}
from collections import deque
class BTNode:
"""二叉树结点(链式存储)"""
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def create_tree(seq_iter):
"""按先序序列创建二叉树,# 表示空结点(seq_iter 为迭代器)"""
try:
ch = next(seq_iter)
except StopIteration:
return None
if ch == '#':
return None
node = BTNode(ch)
node.left = create_tree(seq_iter)
node.right = create_tree(seq_iter)
return node
def pre_order(root):
"""前序:根左右"""
if root is None:
return []
return [root.data] + pre_order(root.left) + pre_order(root.right)
def in_order(root):
"""中序:左根右"""
if root is None:
return []
return in_order(root.left) + [root.data] + in_order(root.right)
def post_order(root):
"""后序:左右根"""
if root is None:
return []
return post_order(root.left) + post_order(root.right) + [root.data]
def level_order(root):
"""层序:用队列"""
if root is None:
return []
result = []
q = deque([root])
while q:
node = q.popleft()
result.append(node.data)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
return result
def height(root):
"""求高度"""
if root is None:
return 0
return max(height(root.left), height(root.right)) + 1
def count_nodes(root):
"""求结点数"""
if root is None:
return 0
return count_nodes(root.left) + count_nodes(root.right) + 1
def count_leaves(root):
"""求叶子数"""
if root is None:
return 0
if root.left is None and root.right is None:
return 1
return count_leaves(root.left) + count_leaves(root.right)
if __name__ == "__main__":
seq = "ABD##E##C#F##"
root = create_tree(iter(seq))
print("前序:", pre_order(root)) # ['A', 'B', 'D', 'E', 'C', 'F']
print("中序:", in_order(root)) # ['D', 'B', 'E', 'A', 'C', 'F']
print("后序:", post_order(root)) # ['D', 'E', 'B', 'F', 'C', 'A']
print("层序:", level_order(root)) # ['A', 'B', 'C', 'D', 'E', 'F']
print("高度:", height(root)) # 3
print("结点数:", count_nodes(root)) # 6
print("叶子数:", count_leaves(root)) # 3