一、单链表的定义和表示 – 知识要点
1.1 定义单链表
1.2 带头结点单链表的初始化
二、单链表 – 定义与初始化
1.1 带头结点代码实现
1.1.1 C语言实现
实现算法实现
#include <stdio.h>
#include <stdlib.h>
// 定义单链表结点结构
typedef struct LNode {
int data; // 数据域(示例用int类型)
struct LNode *next;// 指针域
} LNode, *LinkList; // LinkList为指向LNode的指针类型
// 初始化带头结点的单链表(C语言)
LinkList InitList(LinkList L) {
// 分配头结点内存空间
L = (LNode*)malloc(sizeof(LNode));
if (L == NULL) { // 内存分配失败处理
printf("内存分配失败!\n");
return NULL;
}
L->next = NULL; // 头结点指针域初始化为空
return L; // 返回头结点指针
}
测试主函数
// 测试主函数
int main()
{
LinkList L = NULL; // 声明头指针 等价于 struct LNode* L;
L = InitList(L); // 初始化单链表
if (L != NULL)
{
printf("单链表初始化成功!头结点地址: %p\n", L);
printf("头结点next指针:%s\n", L->next ? "非空" : "空");
}
return 0;
}
运行结果
运行过程
带头结点单链表的初始化的注意点
对单链表定义进行刨析
struct LNode node1; // 传统写法(需要写完整的struct标签) LNode node2; // 等价写法(使用typedef创建的别名)
struct LNode* head1; // 传统写法(需要写完整的struct标签和指针) LinkList head2; // 等价写法(使用typedef创建的指针别名)
总结:为什么这样设计?
这种写法在链表操作中非常实用:
LNode
:表示 “链表结点类型”,用于定义具体的结点变量(如LNode node;
)LinkList
:表示 “链表头指针类型”,用于定义指向链表头结点的指针(如LinkList L;
)。从类型本质看,LinkList
就是struct LNode*
,但用LinkList
命名更符合语义(强调这是 “链表” 的头指针,而不是普通的结点指针)
1.1.2 C++单链表定义及初始化
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
// 定义单链表
typedef struct LNode {
int data; // 数据域
LNode* next;
}LNode,*LinkList;
/**
* 初始化带头结点的单链表(考研标准写法)
* @param L 引用传递的头指针
* @return 初始化成功返回true,失败返回false
*/
bool InitList(LinkList& L)
{
L = new LNode;
if (L == NULL)
{
return false;
}
L->next = NULL;
return true;
}
int main()
{
LinkList L;
if (InitList(L))
{
cout << "链表初始化成功!" << endl;
cout << "头结点地址:" << L << endl;
cout << "头结点next指针:" << (L->next ? "非空" : "空") << endl;
}
else
{
cout << "链表初始化失败!" << endl;
}
return 0;
}
运行结果
代码说明
L = new LNode;
在单链表初始化中的原理是:
- 内存分配:向系统申请
LNode
大小的内存空间。- 对象构造:对
LNode
对象执行默认初始化(成员变量未显式初始化)。- 返回地址:将新分配内存的地址赋值给头指针
L
,使其指向头结点。
结合后续的L->next = NULL
,最终完成 “头结点存在但链表无数据” 的初始化状态。
new
与malloc
的核心区别是:new
会自动调用构造函数(即使是默认构造),而malloc
仅分配内存,不执行任何初始化操作。
1.2 不带头结点代码实现
1.2.1 C语言实现
#include <stdio.h>
#include <stdlib.h>
// 定义单链表结点结构(考研标准写法)
typedef struct LNode {
int data; // 数据域
struct LNode* next; // 指针域(指向下一结点)
} LNode, *LinkList; // LinkList表示链表头指针类型(即struct LNode*)
/**
* 初始化不带头结点的单链表(空链表)
* @param L 头指针的指针(用于修改头指针本身)
* @return 初始化成功返回1,失败返回0(考研中可简化为无返回值)
*/
int InitList(LinkList* L) {
*L = NULL; // 空链表:头指针指向NULL(无任何结点)
return 1; // 初始化总是成功(无内存分配)
}
// 测试主函数(考研答题时可省略,仅用于验证)
int main() {
LinkList L; // 声明头指针(未初始化)
// 初始化单链表(不带头结点)
InitList(&L); // 传递头指针的地址,修改头指针本身
// 验证初始化结果
if (L == NULL) {
printf("单链表初始化成功!当前为空链表(头指针为NULL)\n");
} else {
printf("单链表初始化失败!\n");
}
return 0;
}
运行结果
运行过程
1.2.2 C++实现不带头结点的单链表
#include <iostream>
// 定义单链表结点结构(考研标准写法)
struct LNode {
int data; // 数据域(存储结点值)
LNode* next; // 指针域(指向下一个结点)
};
// 头指针类型别名(语义化:强调是链表的头指针)
using LinkList = LNode*; // LinkList等价于LNode*
/**
* 初始化不带头结点的单链表(空链表)
* @param L 头指针的引用(直接修改主函数中的头指针)
*/
void InitList(LinkList& L) {
L = nullptr; // 空链表:头指针指向nullptr(无任何结点)
}
// 测试主函数(考研答题时可省略,仅用于验证)
int main() {
LinkList L; // 声明头指针(未初始化)
InitList(L); // 初始化单链表(不带头结点)
// 验证初始化结果
if (L == nullptr) {
std::cout << "单链表初始化成功!当前为空链表(头指针为nullptr)" << std::endl;
} else {
std::cout << "单链表初始化失败!" << std::endl;
}
return 0;
}
本网站原创文章版权归何大锤的狂飙日记所有。发布者:何大锤,转转请注明出处:何大锤的博客