跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

线性表、顺序表与链表详解(C 语言实现)

线性表是数据结构基础,包含顺序表和链表两种主要实现。顺序表基于连续内存,支持 O(1) 随机访问但插入删除需移动元素;链表基于非连续内存,插入删除高效但访问需遍历。文章通过 C 语言代码演示了动态顺序表的扩容机制及单向链表的创建、反转与删除操作,对比了两者在时间复杂度、空间开销及应用场景上的差异,帮助读者理解底层存储原理并掌握核心算法逻辑。

Elasticer发布于 2026/3/28更新于 2026/9/1057 浏览
线性表、顺序表与链表详解(C 语言实现)

线性表、顺序表与链表详解(C 语言实现)

学习目标

  1. 理解线性表的逻辑结构和物理实现方式。
  2. 掌握顺序表和链表的实现原理及核心操作。
  3. 能够通过代码实现顺序表和链表的基本功能。
  4. 分析顺序表与链表的性能差异及适用场景。

线性表概述

定义与特性

线性表是由 n 个具有相同特性的元素组成的有限序列,元素之间有明确的前后关系。每个元素有唯一的前驱和后继元素。

  • 逻辑结构:元素在逻辑上依次排列。
  • 物理结构:元素在内存中的存储方式,可以是连续的(顺序表)或不连续的(链表)。

基本特性:

  • 顺序性:元素按顺序访问。
  • 唯一性:除首尾外,每个元素都有唯一前驱和后继。
  • 有限性:包含有限个元素集合。

常见实现方式

线性表主要有两种物理存储方式:顺序存储和链式存储。

顺序存储(顺序表)

使用一段连续的内存空间存储数据,通常使用数组实现。数据元素地址连续,可通过索引直接访问。

  • 优点:随机访问效率高(O(1)),空间利用率高。
  • 缺点:插入删除效率低(需移动元素,O(N)),固定容量可能浪费或不足。
链式存储(链表)

使用非连续的内存空间,每个元素包含数据域和指针域。

  • 优点:插入删除效率高(O(1)),动态分配内存。
  • 缺点:随机访问效率低(O(N)),存在指针开销。

顺序表详解

静态与动态顺序表

  • 静态顺序表:使用固定大小数组,编译时确定大小,适合数据量已知且不变的场景。
  • 动态顺序表:支持动态扩容,容量不足时自动分配更大内存并复制数据,适合数据量不确定的场景。

代码示例(动态顺序表)

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int* array;
    int size;
    int capacity;
} DynamicArray;

void init {
    arr->capacity = ;
    arr->size = ;
    arr-> = (*)(arr->capacity * ());
}

  {
    arr-> = (*)(arr->, new_capacity * ());
    arr->capacity = new_capacity;
}

  {
     (arr->size == arr->capacity) {
        resize(arr,  * arr->capacity);
    }
    arr->[arr->size] = value;
    arr->size++;
}

  {
     ( i = ; i < arr->size; i++) {
        (, arr->[i]);
    }
    ();
}

  {
    (arr->);
}

  {
    DynamicArray arr;
    init(&arr);
    append(&arr, );
    append(&arr, );
    append(&arr, );
    append(&arr, ); 
    print_array(&arr);
    free_array(&arr);
     ;
}
(DynamicArray* arr)
2
0
array
int
malloc
sizeof
int
void
resize
(DynamicArray* arr, int new_capacity)
array
int
realloc
array
sizeof
int
void
append
(DynamicArray* arr, int value)
if
2
array
void
print_array
(DynamicArray* arr)
for
int
0
printf
"%d "
array
printf
"\n"
void
free_array
(DynamicArray* arr)
free
array
int
main
()
1
2
3
4
// 触发扩容
return
0

链表详解

基本操作

  • 初始化:创建空链表,可使用虚拟头节点简化操作。
  • 插入/删除:修改指针链接,无需移动元素。
  • 查找:遍历链表。
  • 反转:调整指针指向。

代码示例(单向链表)

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int val;
    struct ListNode* next;
};

// 尾插法创建链表
struct ListNode* create_linked_list_tail(int* values, int size) {
    struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode* tail = dummy;
    for (int i = 0; i < size; i++) {
        struct ListNode* new_node = (struct ListNode*)malloc(sizeof(struct ListNode));
        new_node->val = values[i];
        tail->next = new_node;
        tail = tail->next;
    }
    return dummy->next;
}

void print_linked_list(struct ListNode* head) {
    struct ListNode* current = head;
    while (current != NULL) {
        printf("%d ", current->val);
        current = current->next;
    }
    printf("\n");
}

// 反转链表
struct ListNode* reverse_linked_list(struct ListNode* head) {
    struct ListNode* prev = NULL;
    struct ListNode* curr = head;
    while (curr != NULL) {
        struct ListNode* next_node = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next_node;
    }
    return prev;
}

int main() {
    int values[] = {1, 2, 3};
    struct ListNode* head = create_linked_list_tail(values, 3);
    print_linked_list(head);
    return 0;
}

对比分析

特性顺序表链表
存储方式连续内存块离散内存块,通过指针链接
随机访问O(1)O(N)
插入/删除O(N)(需移动元素)O(1)(只需修改指针)
空间管理动态扩容可能浪费空间按需分配
缓存局部性高低

实践练习

  1. 顺序表:实现函数删除所有等于给定值的元素。
  2. 链表:合并两个有序链表。
  3. 分析:分析顺序表动态扩容均摊时间复杂度为何是 O(1)。

总结

本文通过 C 语言代码演示了顺序表和链表的实现原理。顺序表适合频繁读取场景,链表适合频繁增删场景。掌握指针操作与内存管理是理解数据结构的关键。

目录

  1. 线性表、顺序表与链表详解(C 语言实现)
  2. 学习目标
  3. 线性表概述
  4. 定义与特性
  5. 常见实现方式
  6. 顺序存储(顺序表)
  7. 链式存储(链表)
  8. 顺序表详解
  9. 静态与动态顺序表
  10. 代码示例(动态顺序表)
  11. 链表详解
  12. 基本操作
  13. 代码示例(单向链表)
  14. 对比分析
  15. 实践练习
  16. 总结

更多推荐文章

查看全部
  • Home Assistant 接入小米智能家居设备本地化部署指南
  • IDEA REST Client 接口调试与协作实战指南
  • AIGC 核心技术解析:GPT、BERT 与 Transformer 工作原理
  • Python 爬虫就业要求与学习路径指南
  • 彻底关闭Win10中烦人的365 Copilot弹窗的6种方法
  • 网页滚动定位导航特效实现
  • 本地服务秒变公网地址:内网穿透演示实战
  • Effective C++ 条款 34:区分接口继承与实现继承
  • Ubuntu 20.04 虚拟机安装与配置实战指南
  • 前端拖拽排序实现详解:从原理到实战
  • 从零构建 AI 对话平台:原生前端实战指南
  • Python 属性描述符:从原理到 ORM 实践详解
  • 基于 Python 和 LLM 的本地 RAG 系统构建指南
  • Python 实现 AI 绘画用户评价自动分类与分析报告生成
  • Vue 3 实战:10 个提升开发效率的常用技巧
  • Llama-2-7B 昇腾 NPU 性能测评与部署实践指南
  • OpenClaw 运行原理剖析:个人 AI 操作系统引擎解析
  • 万方 AIGC 检测难通过?主流降重工具实测对比
  • Antigravity:一款支持多模型的免费 AI 编程工具
  • 在 Jetson 上部署 OpenClaw 并接入飞书机器人打造本地 AI 助手

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online