菜单

C 和 C++ 实现

相关源文件

本页详细介绍了 Hello Algo 仓库中 C 和 C++ 数据结构与算法的实现。这些实现遵循了语言的惯用模式,并保持了仓库内所有语言版本接口的一致性。其他语言的实现请参考相应的页面,例如 Python 实现Rust 实现

实现结构

本仓库中的 C/C++ 实现采用了结构化的方法,包括头文件、通用工具和特定语言的内存管理。

目录结构

来源: .gitattributes, codes/c/chapter_array_and_linkedlist/CMakeLists.txt, codes/c/chapter_stack_and_queue/CMakeLists.txt

常见模式

C 和 C++ 实现都遵循这些通用模式

  1. 每个文件通常实现单个数据结构或算法
  2. 通用工具从 utils/common.h (C) 或 utils/common.hpp (C++) 导入
  3. 代码按主题组织到章节(目录)中
  4. 每个实现都包含一个驱动代码部分(main() 函数),演示了用法

C 实现方法

内存管理模型

Hello Algo 仓库中的 C 实现遵循一致的内存管理模式

来源: codes/c/chapter_array_and_linkedlist/my_list.c, codes/c/chapter_stack_and_queue/array_stack.c, codes/c/chapter_tree/binary_search_tree.c

C 实现的关键特征

  1. 构造函数/析构函数模式:每个数据结构都有创建和销毁实例的函数
  2. 显式内存管理:所有内存分配/释放都显式处理
  3. 基于指针的访问:结构体通过指针访问
  4. 基于结构体的封装:相关数据和方法通过结构体分组

示例:结构体定义模式

C 中定义数据结构的典型模式

/* Structure Definition */
typedef struct {
    // Internal data
    // Typically includes size, capacity, and data pointers
} StructureName;

/* Constructor */
StructureName* newStructureName(...) {
    // Allocate memory and initialize
}

/* Destructor */
void delStructureName(StructureName* obj) {
    // Free memory resources
}

/* Operations */
// Various functions that operate on the structure

来源: codes/c/chapter_array_and_linkedlist/my_list.c:9-15, codes/c/chapter_stack_and_queue/array_stack.c:11-15

C++ 实现方法

C++ 实现利用了该语言的面向对象特性和标准模板库 (STL)

  1. STL 用法:实现使用 STL 容器(vector, unordered_map 等)
  2. RAII 模式:资源获取即初始化,用于自动内存管理
  3. 函数模板:使用泛型以获得类型灵活性
  4. 引用参数:函数常使用引用参数而非指针

示例:冒泡排序比较

让我们比较一下 C 和 C++ 中的冒泡排序实现

C语言实现C++ 实现
使用原生数组使用 std::vector
手动交换元素使用 std::swap
纯过程式方法利用 C++ 语言特性
显式管理数组大小Vector 管理大小

来源: codes/c/chapter_sorting/bubble_sort.c, codes/cpp/chapter_sorting/bubble_sort.cpp

C 中的关键数据结构

动态数组实现

C 中动态数组(MyList)的实现展示了基于数组的数据结构的常见模式

关键操作

  • 自动调整大小:当数组容量达到上限时,extendCapacity() 会分配更大的数组
  • 元素管理:用于添加、删除和访问元素的函数
  • 内存管理:用于分配/释放的构造函数/析构函数模式

来源: codes/c/chapter_array_and_linkedlist/my_list.c

链表实现

链表实现演示了基于指针的数据结构

与基于数组的结构不同,链表操作侧重于通过指针进行节点操作。

来源: codes/c/chapter_array_and_linkedlist/linked_list.c

栈实现

该仓库提供了两种 C 语言的栈实现,展示了不同的底层结构

不同实现之间的接口是一致的,而内部表示则不同

  • ArrayStack 使用具有最大尺寸的预分配数组
  • LinkedListStack 通过链接节点指针构建栈

来源: codes/c/chapter_stack_and_queue/array_stack.c, codes/c/chapter_stack_and_queue/linkedlist_stack.c

队列和双端队列实现

与栈类似,队列和双端队列也有基于数组和基于链表的实现

每个实现都保持相同的接口,同时利用不同的数据结构。

来源: codes/c/chapter_stack_and_queue/array_queue.c, codes/c/chapter_stack_and_queue/linkedlist_queue.c, codes/c/chapter_stack_and_queue/array_deque.c, codes/c/chapter_stack_and_queue/linkedlist_deque.c

树实现

二叉树及其变种使用递归树结构实现

AVL 树通过平衡操作扩展了二叉搜索树,以保持 O(log n) 的高度。

来源: codes/c/chapter_tree/binary_search_tree.c, codes/c/chapter_tree/avl_tree.c

哈希表实现

哈希表使用不同的冲突解决策略实现

开放寻址实现使用线性探测和墓碑标记来处理已删除的元素。

来源: codes/c/chapter_hashing/hash_map_open_addressing.c

算法实现

排序算法

该仓库包含多种排序算法,并采用了统一的模式实现

每个排序实现

  1. 接受数组及其大小作为输入
  2. 原地排序
  3. 包含适用的优化

来源: codes/c/chapter_sorting/bubble_sort.c, codes/c/chapter_sorting/insertion_sort.c

搜索算法

二分查找及其变种展示了高效的搜索技术

这些实现展示了不同的二分查找应用,代码差异很小。

来源: codes/c/chapter_searching/binary_search_insertion.c, codes/c/chapter_searching/binary_search_edge.c

内存管理模式

资源获取与释放

C 实现遵循以下内存管理模式

  1. 构造函数-析构函数模式:

    • 构造函数分配内存并初始化数据
    • 析构函数释放所有分配的内存
  2. 内存扩展策略:

    • 动态结构在扩展容量时使用增长因子(通常为 2 倍)
    • 临时内存会在操作期间分配,并在返回前释放
  3. 错误处理:

    • 使用断言检查前置条件(assert()
    • 一些实现返回错误代码或错误指示符

来源: codes/c/chapter_array_and_linkedlist/my_list.c:19-33, codes/c/chapter_stack_and_queue/linkedlist_stack.c:15-31

内存安全注意事项

C 实现处理了多种内存安全问题

  1. 空指针检查:在解引用前验证指针
  2. 边界检查:验证索引是否在有效范围内
  3. 完整清理:确保所有分配的内存都已释放
  4. 临时存储:正确管理临时分配

C 与 C++ 实现比较

仓库中 C 和 C++ 实现的主要区别

方面C语言实现C++ 实现
内存管理手动 (malloc/free)RAII, 智能指针, STL 容器
数据结构自定义结构体定义STL 容器 (vector, map 等)
代码组织基于函数基于类,带有成员函数
算法实现过程式,带显式指针泛型,带模板和 STL 算法
错误处理返回码,断言异常(可能)
资源安全需要手动清理通过析构函数自动处理

来源: codes/c/chapter_sorting/bubble_sort.c, codes/cpp/chapter_sorting/bubble_sort.cpp

结论

Hello Algo 中的 C 和 C++ 实现提供了基础数据结构和算法的清晰示例,采用了适合语言的模式。C 实现侧重于显式内存管理和指针操作,而 C++ 实现则利用 STL 和语言特性来实现更安全、更简洁的代码。两种方法都保持了数据结构之间一致的接口,便于比较实现策略。

来源: codes/c/chapter_array_and_linkedlist/my_list.c, codes/c/chapter_stack_and_queue/array_stack.c, codes/c/chapter_tree/binary_search_tree.c, codes/cpp/chapter_sorting/bubble_sort.cpp