news 2026/8/27 11:00:18

C语言数据结构详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言数据结构详解

C语言数据结构是计算机科学的基石。理解数据在内存中如何组织,以及如何高效地操作它们,是写出高性能程序的关键。
下面我将由浅入深,为你系统性地讲解C语言中的核心数据结构,并配上代码示例。


第一部分:预备知识
在开始之前,有几个C语言的核心概念需要先掌握,它们是实现数据结构的基础:

  1. 指针:数据结构的“粘合剂”。通过指针,我们可以在内存中动态地连接不同块的数据(如链表)。
  2. 动态内存分配:malloc(), calloc(), realloc(), free()。这些函数允许我们在程序运行时(堆上)按需创建和销毁数据,而不是在编译时(栈上)固定大小。
  3. 结构体(struct):用于将不同类型的数据(如 int 和 char*)组合成一个新的自定义数据类型,用来表示数据结构的节点。

第二部分:线性数据结构
线性结构的特点是数据元素之间存在一对一的线性关系。

  1. 数组(Array)
    这是最基础、最紧凑的数据结构,在内存中占据连续的空间。
    • 优点:访问速度快(O(1)时间复杂度),可通过下标直接操作。
    • 缺点:大小固定(静态数组),插入和删除操作效率低(需要移动大量元素)。
    • 实现:
    c
    #include <stdio.h>
    int main() {
    int arr[5] = {1, 2, 3, 4, 5}; // 静态声明
    arr[2] = 10; // 直接访问
    printf(“%d\n”, arr[2]);
    return 0;
    }
  2. 链表(Linked List)
    为了解决数组大小固定和插入删除成本高的问题,链表诞生了。它由一系列节点组成,每个节点包含数据和一个指向下一个节点的指针。
    • 优点:动态大小,插入和删除操作高效(只需修改指针)。
    • 缺点:无法随机访问,查找需要遍历(O(n)时间复杂度),且需要额外的指针存储空间。
    • 实现(单链表节点):
    c
    #include <stdio.h>
    #include <stdlib.h>

// 定义节点结构体
typedef struct Node {
int data;
struct Node* next;
} Node;

// 创建新节点
Node* createNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode == NULL) {
printf(“内存分配失败\n”);
exit(1);
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}

// 在头部插入
void insertAtHead(Node** head, int data) {
Node* newNode = createNode(data);
newNode->next = *head;
*head = newNode;
}

// 遍历打印
void printList(Node* head) {
Node* current = head;
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next;
}
printf(“NULL\n”);
}

int main() {
Node* head = NULL;
insertAtHead(&head, 10);
insertAtHead(&head, 20);
insertAtHead(&head, 30);
printList(head); // 输出:30 -> 20 -> 10 -> NULL
return 0;
}
3. 栈(Stack)
一种后进先出(LIFO,Last In First Out)的数据结构,就像一叠盘子,只能从顶部取放。
• 核心操作:push(压入)、pop(弹出)、peek(查看栈顶)。
• 应用:函数调用栈、表达式求值、撤销操作。
• 实现方式:既可以用数组(顺序栈,简单快速),也可以用链表(链式栈,大小不限)。
4. 队列(Queue)
一种先进先出(FIFO,First In First Out)的数据结构,就像排队买票,先来的人先服务。
• 核心操作:enqueue(入队,从队尾添加)、dequeue(出队,从队首移除)。
• 应用:任务调度、消息队列、广度优先搜索(BFS)。
• 实现方式:通常使用链表实现,或使用“循环数组”来避免顺序队列的假溢出问题。


第三部分:树形数据结构
树形结构具有分层特性,数据元素之间存在一对多的关系。

  1. 二叉树(Binary Tree)
    每个节点最多有两个子节点(左孩子和右孩子),是最重要的树形结构。
    • 关键概念:根节点、叶子节点、深度、前/中/后序遍历。
    • 代码(节点定义与中序遍历):
    c
    typedef struct TreeNode {
    int data;
    struct TreeNode* left;
    struct TreeNode* right;
    } TreeNode;

// 中序遍历:左 -> 根 -> 右
void inorderTraversal(TreeNode* root) {
if (root == NULL) return;
inorderTraversal(root->left);
printf("%d ", root->data);
inorderTraversal(root->right);
}
2. 二叉搜索树(BST,Binary Search Tree)
一种特殊的二叉树,它满足:左子树所有节点的值 < 根节点的值 < 右子树所有节点的值。
• 优点:查找、插入、删除的平均时间复杂度为 O(log n)。
• 缺点:在最坏情况下(如插入有序数据)会退化成链表,复杂度变为 O(n)。
3. 平衡二叉树与堆
• AVL树 / 红黑树:为了解决BST退化问题而设计的自平衡二叉搜索树,保证查找效率稳定在 O(log n)。(C++ STL 中的 std::map 就是红黑树)。
• 堆(Heap):一种特殊的完全二叉树。大顶堆的根节点是最大值,小顶堆的根节点是最小值。它常被用作实现优先队列,堆排序的时间复杂度为 O(n log n)。


第四部分:散列(Hash)与图

  1. 哈希表(Hash Table)
    哈希表通过哈希函数将键(Key)映射到数组中的某个位置,从而实现极快的存取。
    • 优点:查找、插入、删除的平均时间复杂度为 O(1)。
    • 缺点:数据无序,且需要处理哈希冲突(两个不同键映射到同一位置)。
    • 解决冲突的方法:链地址法(同一位置的元素用链表存储)和开放地址法(向后探测空位)。
    • 应用:数据库索引、缓存系统(Redis)。
  2. 图(Graph)
    图用于表示多对多的网络关系,由顶点(Vertex)和边(Edge)组成。
    • 存储方式:
    o 邻接矩阵:使用二维数组,直观但浪费空间(适合稠密图)。
    o 邻接表:使用数组+链表,节省空间(适合稀疏图,也是主流方式)。
    • 核心算法:
    o 深度优先搜索(DFS,Depth-First Search):借助栈(或递归)实现。
    o 广度优先搜索(BFS,Breadth-First Search):借助队列实现。
    o 最短路径:Dijkstra算法、Floyd算法。

第五部分:如何选择数据结构?
在实际开发中,没有“最好”的数据结构,只有“最合适”的。你可以参考这个决策流程:

  1. 需要频繁通过下标访问吗? -> 用数组。
  2. 大小动态变化,且频繁在中间插入/删除? -> 用链表。
  3. 需要“后进先出”处理数据? -> 用栈。
  4. 需要“先进先出”处理数据? -> 用队列。
  5. 需要快速查找(且数据有序)? -> 用二叉搜索树。
  6. 需要近乎瞬间的查找(按键取值)? -> 用哈希表。
  7. 需要处理复杂的关系网络(如地图导航)? -> 用图。

总结与进阶建议

  1. 纸上画图:在学习链表、树等结构时,建议先在纸上画出节点和指针的连接关系,再对照着写代码,会清晰很多。
  2. 画内存图:理解 malloc 在堆上分配的空间,以及指针变量在栈上存储的地址,这是理解数据结构的关键。
  3. 重视边界条件:在实现时,一定要重点思考空指针(NULL)、空表、表头和表尾等特殊情况的处理。
  4. 学习路线:如果刚开始学习,可以按照数组 -> 链表 -> 栈与队列 -> 树 -> 哈希表 -> 图这个顺序来逐步深入。
    数据结构的学习需要大量的编码练习。如果你对上面某个具体结构(比如二叉树的非递归遍历、哈希表的完整实现)感兴趣,或者想看看完整的代码示例,可以告诉我,我们可以深入聊聊。祝你学习顺利!😊
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/27 10:59:12

700V HVIC如何破解高侧驱动难题:可靠性与面积的双重优化

做电源设计这些年&#xff0c;最怕听到的一句话就是“上管又炸了”。桥式拓扑里&#xff0c;只要涉及半桥、全桥、图腾柱PFC、LLC或者有源钳位反激&#xff0c;就绕不开高侧MOSFET或者IGBT的栅极驱动问题。早年没接触700 V HVIC的时候&#xff0c;我一直在用隔离变压器、光耦加…

作者头像 李华
网站建设 2026/8/27 10:58:14

Turbo系统论文解析:LLM推理加速的关键技术与工程验证

这一篇论文记录写的是第 25 篇&#xff0c;对象是《Turbo》&#xff0c;会议标注是 SIGCOMM 2026。单看标题和会议方向&#xff0c;可以先给出一个基本判断&#xff1a;它不是一篇纯算法论文&#xff0c;而是一篇系统方向的工作&#xff0c;目标是把 LLM 推理过程中的某个瓶颈加…

作者头像 李华
网站建设 2026/8/27 10:56:55

9800X3D+RX 9070 XT 1.6万元高性价比游戏主机装机方案

最近后台收到不少游戏玩家的配置咨询&#xff0c;预算都集中在 1.6 万元附近&#xff0c;要求很明确&#xff1a;主攻游戏&#xff0c;CPU 锁定 AMD Ryzen 7 9800X3D&#xff0c;显卡指定华硕 RX 9070 XT。这个组合恰好是 2025 年 AMD 阵营里讨论度很高的“3A 游戏黄金搭档”&a…

作者头像 李华
网站建设 2026/8/27 10:56:08

液冷项目验收:浸没式冷却液检测报告与介质选型合规清单

背景液冷系统验收时&#xff0c;设备侧&#xff08;冷板、管路、CDU&#xff09;的核查流程已相对成熟&#xff0c;但冷却液介质侧的资料合规性&#xff0c;往往是项目延期的高发区。本文从工程验收视角&#xff0c;梳理介质侧三类高频不合规项及应对清单&#xff0c;供设计院、…

作者头像 李华
网站建设 2026/8/27 10:53:55

WeChatMsg:一键把微信聊天记录导出成本地文件,支持HTML/Word/CSV

WeChatMsg&#xff1a;一键把微信聊天记录导出成本地文件&#xff0c;支持HTML/Word/CSV 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/Git…

作者头像 李华