树状结构(Tree)是一种非常常见的数据结构,它由节点(Node)和边(Edge)组成。树状结构中的节点之间存在层级关系,其中一个节点可以作为另一个节点的父节点,而后者则成为前者的子节点。树状结构最顶层的节点称为根节点(Root),没有子节点的节点称为叶节点(Leaf)。
树状结构的特点包括:
每个节点可以有零个或多个子节点。
每个节点除了根节点外,都有且只有一个父节点。
除了根节点外,每个节点可以有兄弟节点,即具有相同父节点的节点。
从根节点到任意节点都存在唯一的路径。
树状结构常用于模拟层次关系的场景,比如组织结构、文件系统、分类目录等。在计算机科学中,树状结构也被广泛应用于算法和数据存储中,例如二叉树、平衡树、树遍历等。
树状结构的一些常见术语包括:
节点(Node):树状结构中的元素,包含数据和指向子节点的指针。
根节点(Root):树的顶层节点,没有父节点。
叶节点(Leaf):没有子节点的节点。
父节点(Parent):一个节点的直接上层节点。
子节点(Child):一个节点的直接下层节点。
兄弟节点(Sibling):具有相同父节点的节点。
子树(Subtree):以某个节点为根节点的子树,包括该节点及其所有后代节点。
树状结构有许多不同的变体,例如二叉树(每个节点最多有两个子节点)、平衡树(保持树的平衡性,如AVL树和红黑树)、B树(用于数据库索引)等。这些变体在不同的应用场景中具有不同的特点和优势。
树状结构可以通过多种方式来表示和实现,包括链式表示法、数组表示法、哈希表表示法等。具体的表示方法取决于应用的需求和具体的算法实现。
#include <stdio.h>
#include <stdlib.h>
// 定义树节点结构体
struct TreeNode {
int data;
struct TreeNode* left;
struct TreeNode* right;
};
// 创建新节点
struct TreeNode* createNode(int data) {
struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// 插入节点
struct TreeNode* insertNode(struct TreeNode* root, int data) {
if (root == NULL) {
return createNode(data);
} else {
if (data < root->data) {
root->left = insertNode(root->left, data);
} else {
root->right = insertNode(root->right, data);
}
return root;
}
}
// 先序遍历
void preorderTraversal(struct TreeNode* root) {
if (root != NULL) {
printf("%d ", root->data);
preorderTraversal(root->left);
preorderTraversal(root->right);
}
}
// 中序遍历
void inorderTraversal(struct TreeNode* root) {
if (root != NULL) {
inorderTraversal(root->left);
printf("%d ", root->data);
inorderTraversal(root->right);
}
}
// 后序遍历
void postorderTraversal(struct TreeNode* root) {
if (root != NULL) {
postorderTraversal(root->left);
postorderTraversal(root->right);
printf("%d ", root->data);
}
}
// 主函数
int main() {
struct TreeNode* root = NULL;
// 插入节点
root = insertNode(root, 50);
insertNode(root, 30);
insertNode(root, 20);
insertNode(root, 40);
insertNode(root, 70);
insertNode(root, 60);
insertNode(root, 80);
// 遍历树
printf("Preorder traversal: ");
preorderTraversal(root);
printf("\n");
printf("Inorder traversal: ");
inorderTraversal(root);
printf("\n");
printf("Postorder traversal: ");
postorderTraversal(root);
printf("\n");
return 0;
}