【王道数据结构笔记】单链表的操作--按位序插入(不带头节点 代码分析)

在这里插入图片描述

🎈个人主页:豌豆射手^
🎉欢迎 👍点赞✍评论⭐收藏
🤗收录专栏:数据结构
🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步!

【王道数据结构笔记】单链表的操作--按位序插入(不带头节点 代码分析)

在这里插入图片描述

引言

一 代码

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个位置)插入新节点的特殊情况的。链表的头部插入是链表操作中的一个常见场景,需要特别注意处理。

  1. 判断插入位置

    if (i == 1)
    

    这行代码检查i是否等于1,即是否要在链表头部插入新节点。

  2. 分配新节点内存

    LNode *s = (LNode *)malloc(sizeof(LNode));
    

    这行代码使用malloc函数为新的链表节点分配内存,并将返回的内存地址赋值给指针sLNode是链表节点的结构体类型,sizeof(LNode)计算该类型的大小。

  3. 检查内存分配是否成功

    if (s == NULL) {
        // 处理内存分配失败的情况
        return false;
    }
    

    分配内存后,代码检查s是否为NULL。如果malloc失败(例如,由于内存不足),它将返回NULL。在这种情况下,代码不会继续执行插入操作,而是返回false,表示插入失败。

  4. 设置新节点的数据

    s->data = e;
    

    这行代码将新节点的数据域设置为传入的参数e

  5. 设置新节点的next指针

    s->next = L;
    

    由于新节点将被插入到链表的头部,它的next指针应指向原链表的头节点。这里L是原链表的头节点指针。

  6. 更新链表头指针

    L = s;
    

    这行代码将链表头指针L更新为新节点的地址。这样,新节点就成为了新的链表头节点。

  7. 返回插入成功的结果

    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++; // 计数器递增
}

五. 检查是否找到插入位置的前驱节点
如果pNULL,说明链表长度小于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)


  • 17
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
链表是一种常见的数据结构,它由一个或多个节点组成,每个节点包含一个数据域和一个指针域,指针域指向下一个节点。 实现链表的查找位算法函数需要以下步骤: 1. 定义一个指针p指向链表的头节点,并定义一个变量count,用于计数。 2. 从头节点开始,遍历链表,当p指向某个节点时,计数器count加1。 3. 如果p指向的节点的数据与目标数据相等,则返回当前的计数器count,即为目标数据的位。 4. 如果p指向的节点不是目标数据,则将p指向下一个节点,重复步骤3。 5. 如果遍历完链表后仍未找到目标数据,则返回-1,表示未找到。 下面是C语言实现链表查找位算法函数的代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义链表节点结构 typedef struct Node { int data; // 数据域 struct Node* next; // 指针域 } Node; // 查找位的算法函数 int findPosition(Node* head, int target) { Node* p = head; // 指向头节点 int count = 0; // 计数器初始化为0 while (p != NULL) { count++; // 计数器加1 if (p->data == target) { return count; // 找到目标数据,返回当前计数器的值 } p = p->next; // 指向下一个节点 } return -1; // 遍历完链表未找到目标数据,返回-1 } int main() { // 创建链表 Node* head = (Node*)malloc(sizeof(Node)); head->data = 1; // 头节点数据为1 Node* node1 = (Node*)malloc(sizeof(Node)); node1->data = 2; Node* node2 = (Node*)malloc(sizeof(Node)); node2->data = 3; head->next = node1; node1->next = node2; node2->next = NULL; // 查找位示例 int target = 3; // 目标数据为3 int position = findPosition(head, target); if (position != -1) { printf("目标数据 %d 的位为 %d\n", target, position); } else { printf("未找到目标数据 %d\n", target); } // 释放链表内存 free(node2); free(node1); free(head); return 0; } ``` 在上述代码中,我们首先定义了一个指向头节点的指针p和一个计数器count,然后使用while循环遍历链表。当p指向某个节点时,计数器加1,并判断该节点的数据是否与目标数据相等。如果找到了目标数据,则返回当前计数器的值,即为目标数据的位。如果遍历完链表仍未找到目标数据,则返回-1表示未找到。最后在主函数中演示了调用该算法函数的示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值