2025-03-19 学习记录--C/C++-C语言-单链表的结构体定义 + LNode * 和 LinkList 的区别
C
语言-单链表的结构体定义 ⭐️
一、单链表的结构体定义 🍭
typedef struct LNode { // 定义结构体 LNode,表示链表中的一个结点
int data; // 数据域,存储结点的值
struct LNode *next; // 指针域,指向下一个结点
} LNode, *LinkList; // 为结构体 LNode 定义两个别名:LNode 和 LinkList
代码功能说明: 🎀
- 定义链表结点结构体:🍉
LNode
是链表中的一个结点,包含两个成员:👇🏻
data
:存储结点的值(整数类型)。next
:指向下一个结点的指针。- 定义别名:🍉
LNode
:表示一个链表结点。LinkList
:表示指向链表结点的指针(通常用于表示链表的头指针)。代码逻辑详解: 🎀
- 结构体定义:🍉
struct LNode
定义了一个链表结点的结构体。data
是结点的数据域,用于存储整数值。next
是结点的指针域,指向下一个结点。- 别名定义:🍉
typedef
为struct LNode
定义了两个别名:LNode
:表示一个链表结点。LinkList
:表示指向链表结点的指针(通常用于表示链表的头指针)。
#include <stdio.h> // 包含标准输入输出库,用于使用printf等函数
#include <stdlib.h> // 包含标准库函数,用于使用malloc等函数
// 定义链表结点的结构体
typedef struct LNode {
int data; // 数据域,存储结点的值
struct LNode *next; // 指针域,指向下一个结点
} LNode, *LinkList; // 为结构体 LNode 定义两个别名:LNode 和 LinkList
// 创建一个新结点
LNode *createNode(int data) {
LNode *newNode = (LNode *)malloc(sizeof(LNode)); // 动态分配内存,创建一个新结点
newNode->data = data; // 设置新结点的数据域
newNode->next = NULL; // 设置新结点的指针域为NULL
return newNode; // 返回新结点的指针
}
// 打印链表
void printList(LinkList L) {
LNode *p = L; // 定义指针p,指向链表的头结点
while (p != NULL) { // 遍历链表,直到p为NULL
printf("%d -> ", p->data); // 打印当前结点的值
p = p->next; // 移动到下一个结点
}
printf("NULL\n"); // 打印链表结束标志
}
int main() {
// 创建链表 1 -> 2 -> 3 -> NULL
LinkList L = createNode(1); // 创建头结点,值为1
L->next = createNode(2); // 创建第二个结点,值为2
L->next->next = createNode(3); // 创建第三个结点,值为3
// 打印链表
printList(L); // 调用printList函数,打印链表
return 0; // 程序正常结束
}
二、LNode *
和 LinkList
的区别 🍭
// 【写法1】
LNode *p;
p = L -> next;
// 【写法2】
LinkList p;
p = L -> next;
LNode
侧重于表示链表中的每个结点;LinkList
侧重于表示一个链表。
- 一般用头指针表示一个链表,比如:链表
L
表示为:LinkList L;
LNode *
和 LinkList
的区别主要体现在 语义 和 用法 上,尽管它们在语法上是等价的(都是指向 LNode
结构体的指针)。以下是它们的详细区别:👇🏻
(一)、 定义 📚
LNode *
:
- 表示指向
LNode
结构体的指针。- 通常用于表示链表中的某个结点。
LinkList
:
- 是
LNode *
的别名,通过typedef
定义。- 通常用于表示链表的头指针,强调链表的整体性。
(二)、 语义 🌲
LNode *
:
- 强调指向某个具体的链表结点。
- 适合用于操作链表中的某个结点(如插入、删除、遍历等)。
LinkList
:
- 强调指向链表的头结点,表示整个链表。
- 适合用于表示链表的整体(如创建链表、打印链表等)。
(三)、 用法 🪜
LNode *
:用于操作链表中的某个结点。
示例: 🌰
LNode *p = head; // p 指向链表的头结点
while (p != NULL) {
printf("%d ", p->data); // 打印当前结点的值
p = p->next; // 移动到下一个结点
}
LinkList
:用于表示链表的头指针,通常用于函数参数或返回值。
示例: 🌰
LinkList createList() {
LinkList L = (LNode *)malloc(sizeof(LNode)); // 创建头结点
L->next = NULL;
return L; // 返回链表的头指针
}
(四)、 代码示例 🍪
以下是一个完整的代码示例,展示
LNode *
和LinkList
的用法: 👇🏻
#include <stdio.h> // 引入标准输入输出库,用于使用 printf 等函数
#include <stdlib.h> // 引入标准库,用于使用 malloc 和 free 等函数
// 定义链表结点结构体
typedef struct LNode {
int data; // 结点的数据域,存储整型数据
struct LNode *next; // 结点的指针域,指向下一个结点
} LNode, *LinkList; // LNode 是结点类型,LinkList 是指向 LNode 的指针类型
// 创建一个新结点
LNode *createNode(int data) {
LNode *newNode = (LNode *)malloc(sizeof(LNode)); // 动态分配内存,创建一个新结点
newNode->data = data; // 设置新结点的数据域
newNode->next = NULL; // 初始化新结点的指针域为 NULL
return newNode; // 返回新结点的指针
}
// 打印链表
void printList(LinkList L) {
LNode *p = L; // 初始化指针 p,指向链表的头结点
while (p != NULL) { // 遍历链表,直到链表结束
printf("%d -> ", p->data); // 输出当前结点的数据
p = p->next; // 移动到下一个结点
}
printf("NULL\n"); // 输出链表结束标志 NULL
}
// 创建链表
LinkList createList() {
LinkList L = createNode(0); // 创建头结点,数据域为 0
LNode *p = L; // 初始化指针 p,指向链表的头结点
for (int i = 1; i <= 3; i++) { // 循环插入 3 个新结点
p->next = createNode(i); // 在链表尾部插入新结点
p = p->next; // 移动指针 p 到新插入的结点
}
return L; // 返回链表的头指针
}
int main() {
LinkList L = createList(); // 创建链表
printList(L); // 打印链表
// 释放链表内存
LNode *p = L; // 初始化指针 p,指向链表的头结点
while (p != NULL) { // 遍历链表,释放每个结点的内存
LNode *temp = p; // 临时指针 temp 指向当前结点
p = p->next; // 移动指针 p 到下一个结点
free(temp); // 释放当前结点的内存
}
return 0; // 程序正常结束
}
0 -> 1 -> 2 -> 3 -> NULL
(五)、 总结 🌈
特性 | LNode * | LinkList |
---|---|---|
定义 | 指向 LNode 结构体的指针 | LNode * 的别名 |
语义 | 强调指向某个具体的链表结点 | 强调指向链表的头结点,表示整个链表 |
用法 | 用于操作链表中的某个结点 | 用于表示链表的头指针 |
适用场景 | 遍历、插入、删除等操作 | 创建链表、返回链表头指针等操作 |
LNode *
更适合用于操作 链表中的某个结点。LinkList
更适合用于表示 链表的整体(头指针)。