一、单链表的定义
定义: 线性表的链式存储又称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。
typedef struct LNode{//定义单链表结点类型ElemType data; //数据域
struct LNode *next;//指针域
}LNode, *LinkList;
可以利用typedef关键字——数据类型重命名:type<数据类型><别名>
二、单链表的两种实现方式:
1.不带头结点的单链表
```bash
typedef struct LNode{ ElemType data; struct LNode *next;
}LNode, *LinkList;
//初始化一个空的单链表
bool InitList(LinkList &L){ //注意用引用 & L = NULL; //空表,暂时还没有任何结点;
return true;
}
void test(){
LinkList L; //声明一个指向单链表的指针: 头指针
//初始化一个空表InitList(L);
//...
}
//判断单链表是否为空
bool Empty(LinkList L){ if (L == NULL)
return true;
else
return false;
}
头结点:代表链表上头指针指向的第一个结点,不带有任何数据。
2.带头结点的单链表
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;
}
void test(){
LinkList L; //声明一个指向单链表的指针: 头指针
//初始化一个空表InitList(L);
//...
}
//判断单链表是否为空(带头结点) bool Empty(LinkList L){
if (L->next == NULL) return true;
else
return false;
}
3.带头结点和不带头结点的比较:
不带头结点:写代码麻烦!对第一个数据节点和后续数据节点的处理需要用不同的代码逻辑,对空表和 非空表的处理也需要用不同的代码逻辑; 头指针指向的结点用于存放实际数据;
带头结点:头指针指向的头结点不存放实际数据,头结点指向的下一个结点才存放实际数据;
三、学习心得
1.对单链表定义的理解:
单链表是一种动态的数据结构,可以在运行时动态地插入或删除节点,不像数组需要预先定义大小。
单链表的节点由两部分组成:数据域和指针域。数据域用于存储数据,而指针域则存储指向下一个节点的指针。
所有节点通过指针相连,形成链表。每个节点只有一个指针指向下一个节点,这就是“单链表”名称的由来。
2.不带头结点的单链表:
在不带头结点的单链表中,链表的第一个节点便是链表的第一个数据元素,即链表的“头部”是数据节点。
初始化时,头指针直接设置为NULL,表示一个空表。
在进行操作时,如插入、删除,需要特别注意边界条件,比如在表头插入或删除节点时的特殊处理。
3.带头结点的单链表:
带头结点的单链表在链表的最前面多出一个特殊的节点,即头结点。头结点不存储数据,只存储指向第一个实际数据节点的指针。
初始化时,需要分配内存给头结点,并将头结点的指针域设置为NULL。
带头结点的单链表简化了链表操作,因为在表头插入或删除节点时,处理方式与其他位置的节点一致。
4.两种实现方式的比较:
代码的简洁:带头结点的单链表使得链表操作更加统一和简洁,因为所有的节点操作都可以假设存在一个前驱节点,从而简化算法的复杂性。
功能的实现:不带头结点的单链表在实现某些功能时可能需要特殊处理,比如在链表头部进行插入或删除操作。
空间占用:带头结点的单链表多占用了一个节点的空间,虽然这对于大多数应用来说不是问题,但在极端的内存约束环境下可能需要考虑。
使用场景:不带头结点的单链表适用于空间使用受限或需要频繁访问第一个元素的场合。带头结点的单链表则在编程上更为便捷,适用于大多数场景。
5.总体心得:
学习单链表的操作和实现,强化了对动态内存分配的理解,因为链表的节点通常是在运行时动态分配的。
了解到在实现数据结构时,抽象层的设计(如是否使用头结点)会对实现细节和操作复杂度产生影响。
掌握了指针的使用,尤其是在创建、遍历和删除链表节点时对指针操作的理解。
增强了对于链表和数组等数据结构在不同使用场景下的选择和取舍,理解了它们的优势和局限。
通过实践,提高了解决问题的能力,比如在链表操作中考虑特殊情况,如空链表、只有一个节点的链表等。