目录
2.3_1 单链表的定义
一、什么是单链表
用链式存储的线性表统称为链表。
二、用代码定义一个单链表
(1)结构体变量和结构体类型的定义
首先,我们按照之前 C/C++ 中学过的语法来定义一个结构体时是这样的:
struct LNode{ // 定义单链表结点类型
ElemType data; // 数据域
struct LNode *next; // 指针域
};
// 在内存中申请一个结点所需的空间,并用指针p指向这个结点
struct LNode *p = (struct LNode *)malloc(sizeof(struct LNode));
一句代码写得很长,有一个更方便的写法,引入 typedef 关键字进行数据类型重命名,把全名自定义成自己起的小名,使用起来更快捷。
typedef <数据类型> <别名>;
typedef 关键字,将 struct LNode 这个结构体类型名字重新定义为 LNode 和 *LinkList(用来表示指向struct LNmde的指针);
下次想定义一个 struct LNode 结构体变量时,直接 LNode 变量名,就可以了;
初次修改代码为:
struct LNode{
ElemType data;
sruct LNode *next;
};
typedef struct LNode LNode;
// 在使用它生成新结点时的代码:
LNode *p = (LNode *)malloc(sizeof(LNode));
参考菜鸟教程链接:结构体变量和结构体类型的定义 | 菜鸟教程
*LinkList 是结构体指针,使用结构体指针对结构成员的访问(比如做遍历输出数据域时),与结构变量对结构成员的访问在表达方式上有所不同,结构指针对结构成员的访问表示为:结构指针名 -> 结构成员(与 . 优先级有关)
增加一个结构体指针之后的代码:
struct LNode{
ElemType data;
sruct LNode *next;
};
typedef struct LNode LNode;
typedef struct Lnode *LinkList;
// 在使用它生成新结点时的代码:
// 要表示一个单链表时,只需要声明一个头指针L,指向单链表的第一个结点
LNode *L; // 声明一个指向单链表第一个结点的指针
// 或
LinkList L;
而它的效果和下面的代码是一样的,所以我们定义单链表时用如下形式,LNode * 强调“返回的是一个结点”,LinkList 强调“这是一个单链表”,两者根据不同的场景使用会使代码可读性更高。
// 单链表定义
typedef struct LNode{ // 定义单链表结点类型
ElemType data; // 每个结点存放一个数据元素
struct LNode *next; // 指针指向下一个结点
}LNode, *LinkList;
(2)不带头结点的链表
// 20220331 补充代码
// 2.3_1 单链表的定义——不带头结点的链表初始化、判空
#include<iostream>
using namespace std;
# define ElemType int
typedef struct LNode{ // 定义单链表结点类型
ElemType data; // 每个结点存放一个数据元素
struct LNode *next; // 指针指向下一个结点
}LNode, *LinkList;
// 初始化一个空的单链表
bool InitList(LinkList &L){
L = NULL; // 空表,暂时还没有任何结点(防止脏数据)
return true;
}
// 判断单链表是否为空
bool Empty(LinkList L){
return (L == NULL);
}
int main(){
// 声明一个不带头结点的单链表L
LinkList L;
// 初始化
bool InitFlag = 0;
InitFlag = InitList(L);
if(InitFlag) cout << "该不带头结点的单链表初始化成功!" << endl;
else cout << "该不带头结点的单链表初始化不成功。" << endl;
// 判空
bool EmptyFlag = 0;
EmptyFlag = Empty(L);
if(Empty(L)) cout << "该表为空!" << endl;
else cout << "该表不为空。" << endl;
return 0;
}
(3)带头结点的单链表
// 20220401 补充代码
// 2.3_1 单链表的定义——带头结点链表的初始化、判空
#include <iostream>
#include <cstdlib>
using namespace std;
#define ElemType int
typedef struct LNode{ // 定义单链表结点类型
ElemType 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;
}
// 判断单链表是否为空(带头结点)
bool Empty(LinkList L){
return (L->next == NULL);
}
int main(){
// 声明一个指向单链表的指针