🎈个人主页:豌豆射手^
🎉欢迎 👍点赞✍评论⭐收藏
🤗收录专栏:数据结构
🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步!
引言
一 代码
bool ListInsert(LinkList& L, int i, int e)
{
if (i < 1)
return false;
if (i == 1)
{
LNode *s = (LNode *)malloc(sizeof(LNode));
s->data = e;
s->next = L;
L = s;
return false;
}
LNode* p;
int j = 1;
p = L;
while (p != NULL && j < i - 1)
{
p = p->next;
j++;
}
if (p == NULL)//i值不合法
return false;
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
二 代码分析
下面是针对给定代码的分析和代码拆分:
步骤分析
一. 检查插入位置的合法性:
代码首先检查i
是否小于1,因为链表的位序是从1开始的。如果i
小于1,则插入位置不合法,函数直接返回false
。
if (i < 1)
return false;
二. 处理特殊情况:插入到链表头部:
如果i
等于1,表示要在链表的头部插入新节点。此时代码需要分配新节点的内存,设置其数据域,并更新链表的头指针。
if (i == 1)
{
LNode *s = (LNode *)malloc(sizeof(LNode)); // 分配新节点内存
if (s == NULL) {
// 处理内存分配失败的情况
return false;
}
s->data = e; // 设置新节点的数据
s->next = L; // 新节点的next指向原链表头
L = s; // 更新链表头指针
return true; // 插入成功
}
这段代码的具体分析如下:
这段代码是处理在链表的头部(即第1个位置)插入新节点的特殊情况的。链表的头部插入是链表操作中的一个常见场景,需要特别注意处理。
-
判断插入位置:
if (i == 1)
这行代码检查
i
是否等于1,即是否要在链表头部插入新节点。 -
分配新节点内存:
LNode *s = (LNode *)malloc(sizeof(LNode));
这行代码使用
malloc
函数为新的链表节点分配内存,并将返回的内存地址赋值给指针s
。LNode
是链表节点的结构体类型,sizeof(LNode)
计算该类型的大小。 -
检查内存分配是否成功:
if (s == NULL) { // 处理内存分配失败的情况 return false; }
分配内存后,代码检查
s
是否为NULL
。如果malloc
失败(例如,由于内存不足),它将返回NULL
。在这种情况下,代码不会继续执行插入操作,而是返回false
,表示插入失败。 -
设置新节点的数据:
s->data = e;
这行代码将新节点的数据域设置为传入的参数
e
。 -
设置新节点的
next
指针:s->next = L;
由于新节点将被插入到链表的头部,它的
next
指针应指向原链表的头节点。这里L
是原链表的头节点指针。 -
更新链表头指针:
L = s;
这行代码将链表头指针
L
更新为新节点的地址。这样,新节点就成为了新的链表头节点。 -
返回插入成功的结果:
return true;
如果以上步骤都成功执行,则头部插入操作完成,函数返回
true
表示插入成功。
通过这段代码,我们可以看到在链表的头部插入新节点需要特别小心处理,确保内存分配成功,并且正确地更新链表的头指针。这样的处理确保了链表的完整性和正确性。同时,代码还考虑了内存分配失败的情况,这是在实际编程中非常重要的错误处理机制。
注意:这里添加了内存分配失败的判断,这是在实际编程中需要考虑的健壮性处理。
三. 初始化指针和计数器:
初始化一个指针p
用于遍历链表,和一个计数器j
用于记录当前遍历到的位置。p
指向链表的当前头节点。
LNode* p;
int j = 1;
p = L;
四. 遍历链表找到插入位置的前驱节点:
使用while
循环遍历链表,直到找到第i-1
个节点或者链表遍历完。j
用于记录当前遍历到的位置。
while (p != NULL && j < i - 1)
{
p = p->next; // 移动到下一个节点
j++; // 计数器递增
}
五. 检查是否找到插入位置的前驱节点:
如果p
为NULL
,说明链表长度小于i
,即插入位置不合法,函数返回false
。
if (p == NULL)
return false;
六. 创建新节点并插入到链表中:
分配新节点的内存,设置其数据域为e
,然后将新节点插入到p
所指向节点的后面。
LNode* s = (LNode*)malloc(sizeof(LNode)); // 分配新节点内存
if (s == NULL) {
// 处理内存分配失败的情况
return false;
}
s->data = e; // 设置新节点的数据
s->next = p->next; // 新节点的next指向p的下一个节点
p->next = s; // p的next指向新节点,完成插入
同样,这里也添加了内存分配失败的判断。
七 . 返回插入成功的结果:
如果以上步骤都成功执行,则插入操作完成,函数返回true
。
return true;
完整代码
结合上述分析,下面是完整的、包含错误处理和健壮性检查的代码:
bool ListInsert(LinkList& L, int i, int e)
{
if (i < 1)
return false;
if (i == 1)
{
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL) {
return false; // 内存分配失败
}
s->data = e;
s->next = L;
L = s;
return true; // 插入成功
}
LNode* p;
int j = 1;
p = L;
while (p != NULL && j < i - 1)
{
p = p->next;
j++;
}
if (p == NULL)
return false; // 插入位置不合法
LNode* s = (LNode*)malloc(sizeof(LNode));
if (s == NULL) {
return false; // 内存分配失败
}
s->data = e;
s->next = p->next;
p->next = s;
return true; // 插入成功
}
# 总结
> **这篇文章到这里就结束了**
> **谢谢大家的阅读!**
> **如果觉得这篇博客对你有用的话,别忘记三连哦。**
> **我是豌豆射手^,让我们我们下次再见**
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/fba17b1429654fb5ace58e5e3121a13e.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/105c7e264d0648ecbb0f2ae57e263931.png)