P7 链表 链表头前方插入新节点

目录

前言

01 链表头插入数据

示例代码

 02 指定节点前方插入新节点

测试代码


前言

                            

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《C++_@ChenPi的博客-CSDN博客》✨✨✨ 

🔥 推荐专栏2: 《 Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨

📝推荐专栏3: ​​​​​​《 链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
🍉本篇简介  :  链表数据插入之尾插法

✨ 只有我努力了 才有机会接触成功✨

链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。说到这里你应该就明白了,链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。

作为有强大功能的链表,对他的操作当然有许多,比如:

  1. 链表的创建
  2. 链表的链表的遍历打印数据
  3. 链表里面的结构体数据的修改
  4. 链表节点的删除
  5. 链表插入新节点
  6. 链表的数据排序
  7. 链表的反序
  8. 清空链表的元素
  9. 求链表的长度等

在前面几章,我们学习了

  1. 链表的创建
  2. 链表的链表的遍历打印数据
  3. 链表里面的结构体数据的修改
  4. 求链表的长度等
  5. 还有链表结尾插入数据节点,非指定节点
  6. 链表指定节点后方插入数据

 今天我们学链表头的前方插入数据

01 链表头插入数据

今天任务如同所示,我们需要创建一个新的头节点,然后让新的头节点指向旧的头节点, 然后让新的节点成为头节点

所以我们要定义个函数frontInsertDataLink,然后我希望的是,我把头节点的地址以及要插入的数据传进来后创建一个新的头节点,头节点的数据等于我传进来的数据

函数的返回值的话

我希望的是要返回头节点的地址

函数大致如下

我们来解读一下

第23行就是函数体的大概样子了

返回值为struct Link*的 结构体指针,用于放回头节点的地址

参数1是头节点的地址了,参数2就是新节点的数据内容了

第25行:创建1个结构体指针,名为prev,指向头文件

第26-28行:创建1个新的头节点,然后让头节点的data = data

然后让新的头节点的next指向旧的头节点就可以了

我们看一下主函数,看一下这个函数怎么用的

红箭头那里就是该函数的使用了

红框那里则是获取头节点,我们也顺便看一下这么实现的

我们先看一下函数体

函数名getHead,返回值为一个结构体指针,用于返回头节点的地址,有一个参数,此参数就是头节点的数据了

第34到36就是给头节点赋值了

最后返回该节点的地址

我们创建一个新节点接收它就可以

编译完我们看一下结果,没问题,我们先创建了头节点,数据为3

后面从头节点前方再创建新的节点,数据为5

所以打印出来

5 3,正确

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Link
{
    int data;
    struct Link *next;
};

/*打印链表数据*/
void PrintLink(struct Link *head)
{
    struct Link *prev = head;
    while (NULL != prev) 
    {
        printf("%d  ", prev->data);
        prev = prev->next;
    }
    printf("\n");
}
/* 链表头插入数据,不指定位置*/
struct Link* frontInsertDataLink(struct Link *head, int data)
{
    struct Link *prev = head;
    struct Link *newLink = (struct Link *)malloc(sizeof(struct Link));
    newLink->data = data;
    newLink->next = prev;
    return newLink;
}

struct Link *getHead(int data)
{
    struct Link* head = (struct Link*)malloc(sizeof(struct Link));
    head->data = data;
    head->next = NULL;
    return head;
}

int main()
{
    struct Link *head = getHead(3);
    head = frontInsertDataLink(head, 5); 
    PrintLink(head);
    return 0;
}

 02 指定节点前方插入新节点

写到这,好像发现之前写的代码出了点小问题,就是没有检查索引有没有超出范围

这个代码是头插法的最终的最终版本了,

第58行到62行是检测NodeIndex索引有没有越界

第63行到67行就是当索引Nodeindex = 1的时候,就调用前面刚写好的链表头插入新节点函数

68到80行则是链表遍历,根据索引值的多少,找都那个节点,并在索引值对应的节点前插入新节点

我们代码测试一下,索引值写为-1,就是找-1个节点,按道理是没有的,所以应该打印出错信息

 

打印提示越界了,那我们换个正常的试试,比如1

然后就在第一个节点前插入了新节点 

没问题,测试代码如下

测试代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Link
{
	int data;
	struct Link *next;
};

/*打印链表数据*/
void PrintLink(struct Link *head)
{
	struct Link *prev = head;
	while (NULL != prev) 
	{
		printf("%d  ", prev->data);
		prev = prev->next;
	}
	printf("\n");
}

/*获取链表的节点数*/
int GetLinkNum(struct Link *head)
{
	struct Link *prev = head;
	int count = 0;
	while (prev != NULL)
	{
		count++;
		prev = prev->next;
	}
	return count;
}

struct Link *getHead(int data)
{
	struct Link* head = (struct Link*)malloc(sizeof(struct Link));
	head->data = data;
	head->next = NULL;
	return head;
}

/* 链表头插入数据,不指定位置*/
struct Link* frontInsertDataLink(struct Link *head, int data)
{
	struct Link *prev = head;
	struct Link *newLink = (struct Link *)malloc(sizeof(struct Link));
	newLink->data = data;
	newLink->next = prev;
	return newLink;
}


/*链表指定节点前插入新的数据节点*/
struct Link *frontInsertNodeDataLink(struct Link *head,int NodeIndex,int data)
{
	struct Link *prev = head;
	int cnt = 1;
	if(NodeIndex > GetLinkNum(prev)||(NodeIndex<0))  //索引NodeIndex越界
	{
		printf("ERROR: Link index out of range");
		return NULL;
	}
	else if (NodeIndex == 1)  //头接节点前插入数据节点
	{
		prev = frontInsertDataLink(prev,data);
		return prev;
	}
	while (NULL != prev->next)
	{
		if(cnt == NodeIndex-1)
		{
			struct Link *newLink = (struct Link *)malloc(sizeof(struct Link));
			newLink->data = data;
			newLink->next = prev->next;
			prev->next = newLink;
			return head;
		}
		cnt++;
		prev = prev->next;
	}
    return NULL;
}

int main()
{
	struct Link *head = getHead(3);
	head = frontInsertDataLink(head, 5); 
	head = frontInsertDataLink(head, 2); 
	PrintLink(head);
	head = frontInsertNodeDataLink(head, 1,4);
	PrintLink(head);
	return 0;
}

🌺对您有帮助的话记得点赞加关注


🌺如果有说的不对的欢迎指正

  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@ChenPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值