C语言二叉链表构建二叉树:传一级与二级指针实现详解

沈知远
沈知远
发布时间:2026-10-16| 5人浏览过
原创

本文详细讲解如何使用C语言的二叉链表结构,通过先序遍历递归思想创建二叉树。重点对比了“传一级指针”与“传二级指针”两种参数传递方式的底层逻辑差异,并提供包含内存分配检测与先序遍历输出的完整代码示例。

一、二叉链表的定义与创建思想

二叉树是递归定义的树形结构,其最基础的存储方式为二叉链表。使用二叉链表创建二叉树通常遵循先序遍历的顺序:

  1. 根节点:首先访问并创建当前根节点。
  2. 左子树:接着递归创建左子树。
  3. 右子树:最后递归创建右子树。

递归终止条件是输入特定的标识符(如代码中使用的 -1),表示当前节点下不再存在子节点,将其指针设为 NULL 并返回上一级。由于二叉树的创建需要修改指针指向(即改变树的结构),因此在函数设计中,如何传递指针地址是一个关键的技术点。

第一步:定义二叉树节点结构体

为了简化后续编码,建议使用 typedef 对结构体进行重命名,提高代码可读性。

typedef struct Tree{
    int data;                 // 存放数据域
    struct Tree *lchild;      // 指向左子树的指针
    struct Tree *rchild;      // 指向右子树的指针
}Tree, *BitTree;

二、传一级参数实现创建

这种方法的核心在于:函数不直接接收节点的地址,而是创建一个局部指针变量,完成当前节点的赋值后,将指向左/右孩子的结果赋给该局部变量的成员,最后返回根节点的指针。

第1步:编写递归创建函数

入口为无参函数,返回值类型为 BitTree。内部循环读取数据,若数据为 -1 则返回 NULL;否则分配内存并递归。

BitTree CreateLink()
{
    int data;
    int temp;
    BitTree T;
    
    scanf("%d",&data);       // 输入节点数据
    temp=getchar();          // 吸收缓冲区中的空格或换行符
    
    if(data == -1){          // 结束条件:输入-1代表空节点
        return NULL;
    }else{
        T = (BitTree)malloc(sizeof(Tree));   // 为当前节点分配内存
        T->data = data;                      // 存入数据域
        
        printf("请输入%d的左子树: ",data);   
        T->lchild = CreateLink();             // 递归创建左子树,返回值赋给左指针
        
        printf("请输入%d的右子树: ",data);   
        T->rchild = CreateLink();             // 递归创建右子树,返回值赋给右指针
        
        return T;                             // 返回当前创建的根节点
    }  
}

第2步:测试与遍历

调用上述函数获取根节点,并使用先序遍历验证结构是否正确。

void ShowXianXu(BitTree T)   // 先序遍历函数
{
    if(T==NULL)
    {
        return;
    }
    printf("%d ",T->data);
    ShowXianXu(T->lchild);    // 递归遍历左子树
    ShowXianXu(T->rchild);    // 递归遍历右子树
}

int main()
{
    BitTree S;
    printf("请输入第一个节点的数据:\n");
    S = CreateLink();         // 接收返回的根节点
    ShowXianXu(S);            // 输出遍历结果
    
    return 0;  
}

三、传二级参数实现创建

这种方法直接在函数内部修改指针变量本身所指向的内容。函数的参数类型为 BitTree*(即指向指针的指针),无需返回值,因为树结构的建立是通过修改传入的指针地址完成的。

第1步:编写带安全检查的递归函数

由于需要在堆区分配内存,建议增加 if(!(*T)) 的判断以防止内存不足导致程序崩溃。

BitTree CreateLink(BitTree *T)   // T为指向根节点的指针的地址
{
    int data;   
    
    scanf("%d",&data);
    
    if(data == -1){
        *T = NULL;              // 遇到结束标记,将当前层级的指针置为空
    }else{
        *T = (BitTree)malloc(sizeof(Tree));  // 分配内存
        
        if(!(*T)){              // 检查内存是否分配成功
            printf("内存分配失败\n");
            exit(-1);
        }
        
        (*T)->data = data;      // 存入数据
        
        printf("请输入%d的左子树: ",data);
        CreateLink(&((*T)->lchild));    // 递归时传递左指针的地址
        
        printf("请输入%d的右子树: ",data);
        CreateLink(&((*T)->rchild));    // 递归时传递右指针的地址
    }  
}

第2步:主函数中的调用差异

在此模式下,主函数中需定义一个指向指针的变量,并将它的地址传给创建函数。

int main()
{
    BitTree S;                  // S本身即为二叉树根节点指针
    printf("请输入第一个节点的数据:\n");
    CreateLink(&S);             // 传入S的地址,让函数内部能修改S的指向
    ShowXianXu(S);              
    
    return 0;  
}

四、总结

无论是采用“返回一级指针”还是“传入二级指针”,本质上都是为了在递归过程中能够正确地更新父节点中对子节点指针域的引用。
- **一级参数法**逻辑直观,适合初学者理解函数的返回值机制。
- **二级参数法**更贴近底层内存操作,在需要同时处理多个返回值或避免栈空间浪费时更具优势,且便于统一处理指针的空值状态(如 *T=NULL)。

以上就是C语言数据结构之二叉链表创建二叉树的详细内容,更多关于C语言二叉树递归操作的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。