二叉树的基本实现(C语言)

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

本文将介绍如何使用 C 语言实现二叉树的基本操作,包括创建、遍历、统计节点、查找、判断完全二叉树等。代码结构清晰,适合初学者学习和扩展。


📁 项目结构

我们使用三个文件来组织代码:

  • tree.h:声明二叉树结构和相关函数

  • tree.c:实现二叉树的各项功能

  • test.c:测试代码,验证功能是否正确


📘 头文件定义(tree.h)

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

typedef char BTDataType;

typedef struct BinaryTreeNode {
    BTDataType _data;
    struct BinaryTreeNode* _left;
    struct BinaryTreeNode* _right;
} BTNode;

// 函数声明
BTNode* BinaryTreeCreate(BTDataType* a, int* pi);
void BinaryTreeDestory(BTNode* root);
int BinaryTreeSize(BTNode* root);
int BinaryTreeLeafSize(BTNode* root);
int BinaryTreeLevelKSize(BTNode* root, int k);
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
void BinaryTreePrevOrder(BTNode* root);
void BinaryTreeInOrder(BTNode* root);
void BinaryTreePostOrder(BTNode* root);
void BinaryTreeLevelOrder(BTNode* root);
int BinaryTreeComplete(BTNode* root);
int BinaryTreeDepth(BTNode* root);

🔧 功能实现(tree.c)

1. 创建二叉树

使用前序遍历序列(如 "AB#C##DE##F##")构建二叉树,# 表示空节点。

BTNode* BinaryTreeCreate(BTDataType* a, int* pi) {
    assert(a);
    if (a[*pi] == '#') {
        (*pi)++;
        return NULL;
    }
    BTNode* root = (BTNode*)malloc(sizeof(BTNode));
    if (root == NULL) {
        perror("malloc error");
        exit(1);
    }
    root->_data = a[*pi];
    (*pi)++;
    root->_left = BinaryTreeCreate(a, pi);
    root->_right = BinaryTreeCreate(a, pi);
    return root;
}

2. 销毁二叉树

递归释放所有节点内存:

void BinaryTreeDestory(BTNode* root) {
    if (root == NULL) return;
    BinaryTreeDestory(root->_left);
    BinaryTreeDestory(root->_right);
    free(root);
}

3. 统计节点个数

int BinaryTreeSize(BTNode* root) {
    if (root == NULL) return 0;
    return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1;
}

4. 计算二叉树深度

int BinaryTreeDepth(BTNode* root) {
    if (root == NULL) {
        return 0;
    }
    int left = BinaryTreeDepth(root->_left) + 1;
    int right = BinaryTreeDepth(root->_right) + 1;
    return left >= right ? left : right;
}

5. 计算第k层节点个数

int BinaryTreeLevelKSize(BTNode* root, int k) {
    assert(k > 0);
    if (root == NULL) {
        return 0;
    }
    if (k == 1) {
        return 1;
    }
    k--;
    return BinaryTreeLevelKSize(root->_left, k) + BinaryTreeLevelKSize(root->_right, k);
}

6. 查找节点

BTNode* BinaryTreeFind(BTNode* root, BTDataType x) {
    if (root == NULL) return NULL;
    if (root->_data == x) return root;
    BTNode* left = BinaryTreeFind(root->_left, x);
    if (left) return left;
    return BinaryTreeFind(root->_right, x);
}

7. 三种递归遍历(前序、中序、后序)

// 前序遍历:根 -> 左 -> 右
void BinaryTreePrevOrder(BTNode* root) {
    if (root == NULL) return;
    printf("%c ", root->_data);
    BinaryTreePrevOrder(root->_left);
    BinaryTreePrevOrder(root->_right);
}

// 中序遍历:左 -> 根 -> 右
void BinaryTreeInOrder(BTNode* root) {
    if (root == NULL) return;
    BinaryTreeInOrder(root->_left);
    printf("%c ", root->_data);
    BinaryTreeInOrder(root->_right);
}

// 后序遍历:左 -> 右 -> 根
void BinaryTreePostOrder(BTNode* root) {
    if (root == NULL) return;
    BinaryTreePostOrder(root->_left);
    BinaryTreePostOrder(root->_right);
    printf("%c ", root->_data);
}

8. 层序遍历(使用队列)(基于先前博客实现的队列)

需配合一个队列实现:

void BinaryTreeLevelOrder(BTNode* root) {
    if (root == NULL) return;
    Queue q;
    QueueInit(&q);
    QueuePush(&q, root);
    while (!QueueEmpty(&q)) {
        BTNode* head = QueueFront(&q);
        printf("%c ", head->_data);
        if (head->_left) QueuePush(&q, head->_left);
        if (head->_right) QueuePush(&q, head->_right);
        QueuePop(&q);
    }
    QueueDestroy(&q);
}

9. 计算叶子节点个数

int BinaryTreeLeafSize(BTNode* root) {
    if (root == NULL) {
        return 0;
    }
    if (root->_left == NULL && root->_right == NULL) {
        return 1;
    }
    return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}

10. 判断是否是完全二叉树

int BinaryTreeComplete(BTNode* root) {
    if (root == NULL) return 1;
    Queue q;
    QueueInit(&q);
    QueuePush(&q, root);
    while (!QueueEmpty(&q)) {
        BTNode* head = QueueFront(&q);
        if (head == NULL) break;
        QueuePush(&q, head->_left);
        QueuePush(&q, head->_right);
        QueuePop(&q);
    }
    while (!QueueEmpty(&q)) {
        if (QueueFront(&q) != NULL) return 0;
        QueuePop(&q);
    }
    return 1;
}

🧪 测试代码(test.c)

#include "tree.h"

void TestBinaryTree(BTNode* root) {
    char a[] = "AB#C##DE##F##";
    int i = 0;

    //测试创建树
    root = BinaryTreeCreate(a, &i);
    
    //测试计算结点个数
    printf("该二叉树的结点个数为:%d\n", BinaryTreeSize(root));
    
    //测试二叉树的深度
    printf("该二叉树的深度为:%d\n", BinaryTreeDepth(root));
    
    //测试二叉树第k层节点个数
    printf("请输入要查询第几层结点的个数:");
    int k = 0;
    scanf("%d", &k);
    if (k <= BinaryTreeDepth(root))
        printf("第%d层的结点个数为:%d\n", k, BinaryTreeLevelKSize(root, k));
    else printf("超出树的最大深度\n");
    
    //测试二叉树查找值为x的节点
    char c;
    while ((c = getchar()) != '\n' && c != EOF);
    BTDataType x;
    printf("请输入要查找的结点的值:");
    scanf("%c", &x);
    BTNode* node = BinaryTreeFind(root, x);
    if (node) {
        printf("%c\n", node->_data);
    } else {
        printf("不存在该结点\n");
    }
    
    //测试前中后序遍历
    printf("前序遍历:");
    BinaryTreePrevOrder(root);
    printf("\n");
    printf("中序遍历:");
    BinaryTreeInOrder(root);
    printf("\n");
    printf("后序遍历:");
    BinaryTreePostOrder(root);
    printf("\n");
    
    //测试层序遍历
    printf("层序遍历:");
    BinaryTreeLevelOrder(root);
    printf("\n");
    
    //测试叶子结点个数
    printf("叶子结点个数为:%d\n", BinaryTreeLeafSize(root));
    
    //测试判断是否是完全二叉树
    if (BinaryTreeComplete(root)) {
        printf("该二叉树是完全二叉树\n");
    } else {
        printf("该二叉树不是完全二叉树\n");
    }
    
    //测试销毁树
    BinaryTreeDestory(root);
    root = NULL;
}

int main() {
    BTNode* root = NULL;
    TestBinaryTree(root);
    return 0;
}

✅ 功能总结

功能函数名说明
创建BinaryTreeCreate前序遍历序列构建
销毁BinaryTreeDestory递归释放内存
节点数BinaryTreeSize递归统计
叶子数BinaryTreeLeafSize左右子节点为空
第k层节点数BinaryTreeLevelKSize递归至第k层
深度BinaryTreeDepth递归计算最大深度
查找节点BinaryTreeFind递归查找
前中后序遍历Prev/In/PostOrder递归实现
层序遍历LevelOrder队列辅助
判断完全二叉树BinaryTreeComplete层序遍历判断

📌 注意事项

  • 使用 # 表示空节点,构建时需严格对应前序遍历结构

  • 层序遍历和完全二叉树判断需依赖队列实现

  • 销毁二叉树后应将根指针置为 NULL,避免野指针

  • 测试代码中包含了完整的交互式测试流程

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值