C语言需要掌握的基础知识点之树
在C语言中,树(Tree)是一种非常重要的非线性数据结构,它由n(n≥0)个有限节点组成的一个具有层次关系的集合。以下是树的详细介绍:
树的基本概念
树的定义
根节点:树的最顶层节点
父节点、子节点:节点之间的关系
叶子节点:没有子节点的节点
度:节点拥有的子树数
深度:从根节点到该节点的路径长度
高度:从该节点到最远叶子节点的路径长度
二叉树
二叉树节点定义
c
typedef struct TreeNode {
int data;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode;
创建新节点
c
TreeNode* createNode(int data) {
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
树的遍历
深度优先遍历
c
// 前序遍历:根->左->右
void preOrder(TreeNode* root) {
if (root != NULL) {
printf("%d ", root->data);
preOrder(root->left);
preOrder(root->right);
}
}
// 中序遍历:左->根->右
void inOrder(TreeNode* root) {
if (root != NULL) {
inOrder(root->left);
printf("%d ", root->data);
inOrder(root->right);
}
}
// 后序遍历:左->右->根
void postOrder(TreeNode* root) {
if (root != NULL) {
postOrder(root->left);
postOrder(root->right);
printf("%d ", root->data);
}
}
广度优先遍历(层次遍历)
c
void levelOrder(TreeNode* root) {
if (root == NULL) return;
TreeNode* queue[100];
int front = 0, rear = 0;
queue[rear++] = root;
while (front < rear) {
TreeNode* current = queue[front++];
printf("%d ", current->data);
if (current->left != NULL)
queue[rear++] = current->left;
if (current->right != NULL)
queue[rear++] = current->right;
}
}
二叉搜索树(BST)
插入节点
c
TreeNode* insertBST(TreeNode* root, int data) {
if (root == NULL) {
return createNode(data);
}
if (data < root->data) {
root->left = insertBST(root->left, data);
} else if (data > root->data) {
root->right = insertBST(root->right, data);
}
return root;
}
查找节点
c
TreeNode* searchBST(TreeNode* root, int key) {
if (root == NULL || root->data == key) {
return root;
}
if (key < root->data) {
return searchBST(root->left, key);
} else {
return searchBST(root->right, key);
}
}
删除节点
c
TreeNode* deleteBST(TreeNode* root, int key) {
if (root == NULL) return root;
if (key < root->data) {
root->left = deleteBST(root->left, key);
} else if (key > root->data) {
root->right = deleteBST(root->right, key);
} else {
// 节点有一个或没有子节点
if (root->left == NULL) {
TreeNode* temp = root->right;
free(root);
return temp;
} else if (root->right == NULL) {
TreeNode* temp = root->left;
free(root);
return temp;
}
// 节点有两个子节点:找到右子树的最小值
TreeNode* temp = root->right;
while (temp && temp->left != NULL) {
temp = temp->left;
}
root->data = temp->data;
root->right = deleteBST(root->right, temp->data);
}
return root;
}
树的常用操作
计算树的高度
c
int treeHeight(TreeNode* root) {
if (root == NULL) {
return 0;
}
int leftHeight = treeHeight(root->left);
int rightHeight = treeHeight(root->right);
return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
计算节点总数
c
int countNodes(TreeNode* root) {
if (root == NULL) {
return 0;
}
return 1 + countNodes(root->left) + countNodes(root->right);
}
检查是否为完全二叉树
c
int isCompleteTree(TreeNode* root) {
if (root == NULL) return 1;
TreeNode* queue[100];
int front = 0, rear = 0;
int flag = 0; // 标记是否遇到空节点
queue[rear++] = root;
while (front < rear) {
TreeNode* current = queue[front++];
if (current == NULL) {
flag = 1;
} else {
if (flag) return 0; // 如果已经遇到空节点,又遇到非空节点
queue[rear++] = current->left;
queue[rear++] = current->right;
}
}
return 1;
}
完整示例
c
#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode {
int data;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode;
// 创建新节点
TreeNode* createNode(int data) {
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode;
}
// 中序遍历
void inOrder(TreeNode* root) {
if (root != NULL) {
inOrder(root->left);
printf("%d ", root->data);
inOrder(root->right);
}
}
// 插入BST节点
TreeNode* insertBST(TreeNode* root, int data) {
if (root == NULL) return createNode(data);
if (data < root->data)
root->left = insertBST(root->left, data);
else if (data > root->data)
root->right = insertBST(root->right, data);
return root;
}
int main() {
TreeNode* root = NULL;
int values[] = {50, 30, 70, 20, 40, 60, 80};
int n = sizeof(values) / sizeof(values[0]);
// 构建BST
for (int i = 0; i < n; i++) {
root = insertBST(root, values[i]);
}
printf("中序遍历结果: ");
inOrder(root);
printf("\n");
return 0;
}
