二叉树相关知识点
一、二叉树简介
二叉树是一种非线性数据结构,由节点(Node)组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。树的最顶部节点称为根节点(Root),没有子节点的节点称为叶子节点(Leaf)。
二叉树的常见性质包括:
深度:从根节点到某节点的最长路径长度。
高度:从某节点到叶子节点的最长路径长度(通常根节点的高度为树的高度)。
度:节点的子节点数量(二叉树中节点的度不超过2)。
二、二叉树的类型
满二叉树:所有非叶子节点都有两个子节点,且所有叶子节点在同一层。
完全二叉树:除最后一层外,其他层节点数达到最大值,最后一层节点从左到右连续填充。
二叉搜索树(BST):左子树所有节点的值小于根节点,右子树所有节点的值大于根节点。
平衡二叉树(AVL树):任意节点的左右子树高度差不超过1。
三、二叉树的结构定义
在 C 中,我们通常使用 struct 定义树节点:
#include <stdio.h>
#include <stdlib.h>
// 定义二叉树节点结构
struct TreeNode {
int data;
struct TreeNode* left;
struct TreeNode* right;
};
// 为结构体起别名,方便使用
typedef struct TreeNode TreeNode;
四、创建新节点
动态分配内存创建一个新节点:
TreeNode* createNode(int value) {
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
if (!newNode) {
printf("内存分配失败!\n");
return NULL;
}
newNode->data = value;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
五、二叉树的遍历(递归实现)
1. 前序遍历(根 → 左 → 右)
void preorder(TreeNode* root) {
if (root != NULL) {
printf("%d ", root->data);
preorder(root->left);
preorder(root->right);
}
}
2. 中序遍历(左 → 根 → 右)
void inorder(TreeNode* root) {
if (root != NULL) {
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
}
3. 后序遍历(左 → 右 → 根)
void postorder(TreeNode* root) {
if (root != NULL) {
postorder(root->left);
postorder(root->right);
printf("%d ", root->data);
}
}
六、层序遍历(广度优先,BFS)— 使用队列
C 标准库没有现成队列,我们手动实现一个简易队列(基于数组,适用于小规模树):
#define MAX_QUEUE_SIZE 100
typedef struct {
TreeNode* items[MAX_QUEUE_SIZE];
int front, rear;
} Queue;
Queue* createQueue() {
Queue* q = (Queue*)malloc(sizeof(Queue));
q->front = q->rear = -1;
return q;
}
int isEmpty(Queue* q) {
return q->front == -1;
}
void enqueue(Queue* q, TreeNode* node) {
if (q->rear == MAX_QUEUE_SIZE - 1) {
printf("队列已满!\n");
return;
}
if (isEmpty(q)) q->front = 0;
q->items[++(q->rear)] = node;
}
TreeNode* dequeue(Queue* q) {
if (isEmpty(q)) return NULL;
TreeNode* node = q->items[q->front];
if (q->front == q->rear)
q->front = q->rear = -1;
else
q->front++;
return node;
}
层序遍历函数:
void levelOrder(TreeNode* root) {
if (!root) return;
Queue* q = createQueue();
enqueue(q, root);
while (!isEmpty(q)) {
TreeNode* current = dequeue(q);
printf("%d ", current->data);
if (current->left) enqueue(q, current->left);
if (current->right) enqueue(q, current->right);
}
free(q); // 注意:这里只释放了队列结构,未释放每个节点(实际应用中需注意内存管理)
}
七、计算树的高度
int height(TreeNode* root) {
if (root == NULL)
return -1; // 若空树高度为 -1;若定义为空树高度为 0,则返回 0
int leftHeight = height(root->left);
int rightHeight = height(root->right);
return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
八、完整示例程序
构建如下二叉树:
1
/ \
2 3
/ \
4 5
#include <stdio.h>
#include <stdlib.h>
int main() {
TreeNode* root = createNode(1);
root->left = createNode(2);
root->right = createNode(3);
root->left->left = createNode(4);
root->left->right = createNode(5);
printf("前序遍历: ");
preorder(root); // 输出: 1 2 4 5 3
printf("\n");
printf("中序遍历: ");
inorder(root); // 输出: 4 2 5 1 3
printf("\n");
printf("后序遍历: ");
postorder(root); // 输出: 4 5 2 3 1
printf("\n");
printf("层序遍历: ");
levelOrder(root); // 输出: 1 2 3 4 5
printf("\n");
printf("树的高度: %d\n", height(root)); // 输出: 2
return 0;
}
九、内存释放(可选但重要)
为了避免内存泄漏,应递归释放所有节点:
void freeTree(TreeNode* root) {
if (root != NULL) {
freeTree(root->left);
freeTree(root->right);
free(root);
}
}
在 main() 结尾调用:freeTree(root);
十、二叉搜索树(BST)插入
TreeNode* insertBST(TreeNode* root, int value) {
if (root == NULL) {
return createNode(value);
}
if (value < root->data) {
root->left = insertBST(root->left, value);
} else if (value > root->data) {
root->right = insertBST(root->right, value);
}
// 若 value == root->data,可选择忽略或处理重复
return root;
}
总结
- 二叉树在 C 中通过
struct+ 指针实现。 - 动态内存管理(
malloc/free)至关重要。 - 遍历多用递归,但层序遍历需借助队列(可用数组或链表实现)。
- C 语言没有内置容器,需手动实现辅助数据结构(如队列、栈)。
- 实际项目中要注意内存泄漏和空指针检查。
3008

被折叠的 条评论
为什么被折叠?



