二叉树相关知识点

二叉树相关知识点

一、二叉树简介

二叉树是一种非线性数据结构,由节点(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 语言没有内置容器,需手动实现辅助数据结构(如队列、栈)。
  • 实际项目中要注意内存泄漏空指针检查
### 二叉树数据结构知识点总结 #### ### 1. 二叉树的定义 二叉树是一种特殊的树形结构,其中每个节点最多有两个子节点,分别被称为左子节点和右子节点。这种结构使得二叉树具备独特的性质和用途[^2]。 #### ### 2. 节点的基本概念 - **节点**:二叉树中的每一个元素称为节点。 - **度**:一个节点拥有的子树数目称为该节点的度。在二叉树中,任何节点的最大度数为2。 - **叶子节点**:度为0的节点,即没有子节点的节点。 - **分支节点**:度不为0的节点。 - **高度/深度**:从根节点到某个节点最长路径上的边的数量称为该节点的高度或深度。整个二叉树的高度是指从根节点到最远叶子节点的距离[^3]。 #### ### 3. 特殊形式的二叉树 - **满二叉树**:如果一棵二叉树的所有非终端节点都有两个子节点,并且所有叶子都在同一层次,则此二叉树为满二叉树。 - **完全二叉树**:除了最后一层之外,其他各层都被完全填充,并且最后一层的节点都集中在左边的部分区域内的二叉树称为完全二叉树[^4]。 #### ### 4. 二叉树的存储方式 二叉树可以通过两种主要方式进行存储: - **顺序存储**:使用数组来保存二叉树的信息,适用于完全二叉树的情况。 - **链式存储**:通过创建节点对象并设置指向左右子节点的指针来实现。这是更通用的方法,适合各种形态的二叉树[^4]。 ```java class TreeNode { int value; TreeNode leftChild, rightChild; public TreeNode(int item){ this.value = item; leftChild = null; rightChild = null; } } ``` #### ### 5. 二叉树的遍历方法 二叉树的遍历指的是按照某种次序访问树中的所有节点的操作序列。主要有以下几种遍历方式[^5]: - **前序遍历(Pre-order Traversal)** - 访问顺序:根 -> 左子树 -> 右子树。 - **中序遍历(In-order Traversal)** - 访问顺序:左子树 -> 根 -> 右子树。 - **后序遍历(Post-order Traversal)** - 访问顺序:左子树 -> 右子树 -> 根。 每一种遍历都会产生不同的结果列表,这些结果可用于验证某些属性或者重建原始二叉树结构。 --- ####
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值