一、理论知识
二、可运行代码(初始化)
(1)不带头节点
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 定义单链表节点结构体
typedef struct LNode {
int data; // 数据域
struct LNode *next; // 指针域
} LNode, *LinkList;
// 初始化单链表(不带头结点)
bool InitList(LinkList &L) {
L = NULL; // 初始化为空链表,不创建头结点
return true;
}
int main() {
LinkList L;
if (InitList(L)) { // 初始化单链表
printf("单链表初始化成功\n");
} else {
printf("单链表初始化失败\n");
}
return 0;
}
(2)带头节点
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 定义单链表节点结构体
typedef struct LNode {
int data; // 数据域
struct LNode *next; // 指针域
} LNode, *LinkList;
// 初始化单链表(带头结点)
bool InitList(LinkList &L) {
L = (LNode *)malloc(sizeof(LNode)); // 创建头结点
if (L == NULL) { // 内存分配失败
return false;
}
L->next = NULL; // 初始化为空链表
return true;
}
int main() {
LinkList L;
InitList(L); // 初始化单链表
printf("单链表初始化成功\n");
return 0;
}
(3)代码解释:
头文件包含:
#include <stdio.h>
:包含标准输入输出库,用于打印信息到控制台。#include <stdlib.h>
:包含标准库,提供动态内存分配函数malloc
。#include <stdbool.h>
:包含布尔类型支持,提供true
和false
。单链表节点结构体定义:
typedef struct LNode
:定义了一个结构体LNode
,它表示单链表的节点。
int data;
:节点的数据域,用于存储整型数据。struct LNode *next;
:节点的指针域,指向下一个节点。LNode, *LinkList;
:同时定义了LNode
类型的别名和指向LNode
的指针类型LinkList
。初始化单链表函数:
bool InitList(LinkList &L)
:这是一个初始化单链表的函数,接受一个引用类型的LinkList
参数L
。
L = (LNode *)malloc(sizeof(LNode));
:使用malloc
函数动态分配一个LNode
大小的内存空间,作为头结点,并将其地址赋给L
。if (L == NULL) {
return false; }
:检查malloc
是否成功分配内存。如果分配失败(L
为NULL
),则返回false
。L->next = NULL;
:将头结点的指针域设置为NULL
,表示这是一个空链表。return true;
:如果初始化成功,返回true
。main函数:
int main()
:C程序的入口点。
LinkList L;
:声明一个LinkList
类型的变量L
,用于表示单链表。InitList(L);
:调用InitList
函数来初始化单链表,传入L
作为参数。printf("单链表初始化成功\n");
:如果初始化成功,打印一条消息到控制台。return 0;
:表示程序成功执行完毕。
(4) 不带头节点单链表和带头节点单链表在初始化时的主要区别如下:
是否创建头结点:
- 不带头节点的单链表:初始化时不创建头结点,直接将链表头指针设置为
NULL
,表示空链表。- 带头节点的单链表:初始化时创建一个头结点,并将头结点的指针域设置为
NULL
,表示空链表。头结点不存储数据,它的存在主要是为了简化链表操作。内存分配:
- 不带头节点的单链表:初始化函数
InitList
不需要进行内存分配,因为它只是将链表头指针设置为NULL
。- 带头节点的单链表:初始化函数
InitList
需要动态分配内存来创建头结点。返回值:
- 不带头节点的单链表:初始化函数
InitList
总是返回true
,因为将头指针设置为NULL
不会失败。- 带头节点的单链表:初始化函数
InitList
在内存分配失败时会返回false
,否则返回true
。后续操作的影响:
- 不带头节点的单链表:在插入、删除等操作时,需要特别处理第一个元素的情况,因为第一个元素没有前驱结点。
- 带头节点的单链表:由于头结点的存在,第一个元素的前驱结点是头结点,这使得插入、删除等操作更加统一,不需要特别处理第一个元素的情况。