新手入门C语言链表
本文以直白的讲解方式梳理链表学习内容,无复杂术语与晦涩逻辑,适合新手参考学习,阅读后可直接编写基础链表代码。
一、链表基础概念
抛开专业定义,以生活化场景理解链表:链表类似串联的糖葫芦,每一颗山楂代表一个节点,连接山楂的竹签对应节点内的指针。
每个节点包含两部分内容:
- 数据域:存储所需数据,如整型、字符型数据;
- 指针域:存储下一个节点的内存地址,实现节点间的关联。
链表与数组的核心区别在于,链表节点在内存中并非连续存储,依靠指针完成节点串联,可自由实现节点的新增与删除,无需调整其他数据位置。
二、定义链表节点
实现链表的第一步是通过结构体定义节点,代码及逐行注释如下:
|
C #include <stdio.h> #include <stdlib.h> // 调用malloc、free函数需包含该头文件
// 定义链表节点结构体 struct Node { int data; // 数据域,存储整型数据,可根据需求修改数据类型 struct Node *next; // 指针域,存储下一个节点的地址 };
|
代码说明:
- struct Node 为自定义的节点结构体类型;
- data 用于存储具体数据,本文以整型为例,可替换为字符型、浮点型等;
- *next 为结构体指针,指向同类型的下一个节点,实现节点的链式连接。
三、新手必学链表核心操作
链表基础操作共四项,逻辑简单,逐一掌握即可实现完整链表功能。
1. 创建新节点
存储数据前需创建节点,为节点分配内存并赋值,代码如下:
|
C // 功能:创建新节点,返回新节点地址 // 参数:data为需存入节点的数据 struct Node* createNode(int data) { // 为新节点申请内存空间 struct Node *newNode = (struct Node*)malloc(sizeof(struct Node)); // 校验内存申请结果 if (newNode == NULL) { printf("内存申请失败\n"); return NULL; } // 初始化节点数据与指针 newNode->data = data; newNode->next = NULL; return newNode; }
|
注意:通过malloc申请的内存,使用完毕后需手动释放,避免内存泄漏。
2. 尾插法添加节点
尾插法是最常用的节点插入方式,将新节点添加至链表末尾,数据顺序与插入顺序一致,代码如下:
|
C // 功能:向链表尾部插入新节点,返回链表头节点 // 参数:head为链表头节点,data为需插入的数据 struct Node* insertAtTail(struct Node *head, int data) { struct Node *newNode = createNode(data); // 若链表为空,新节点作为头节点 if (head == NULL) { head = newNode; return head; } // 遍历找到链表最后一个节点 struct Node *temp = head; while (temp->next != NULL) { temp = temp->next; } // 将新节点接入链表尾部 temp->next = newNode; return head; }
|
3. 遍历链表打印数据
遍历链表可依次读取并输出所有节点数据,代码如下:
|
C // 功能:遍历链表并打印所有节点数据 // 参数:head为链表头节点 void printList(struct Node *head) { struct Node *temp = head; // 循环遍历至链表末尾 while (temp != NULL) { printf("%d ", temp->data); temp = temp->next; } printf("\n"); }
|
4. 释放链表内存
程序结束后需释放链表所有节点的内存,代码如下:
|
C // 功能:释放链表所有节点内存 // 参数:head为链表头节点 void freeList(struct Node *head) { struct Node *temp; while (head != NULL) { temp = head; head = head->next; free(temp); } }
|
四、完整测试代码
将以上功能整合,编写主函数测试链表操作:
|
C int main() { // 初始化空链表 struct Node *head = NULL; // 向链表添加数据 head = insertAtTail(head, 10); head = insertAtTail(head, 20); head = insertAtTail(head, 30); head = insertAtTail(head, 40); // 打印链表数据 printf("链表数据:"); printList(head); // 释放链表内存 freeList(head); return 0; }
|