目录
前言
01 链表头插入数据
示例代码
02 指定节点前方插入新节点
测试代码
个人主页:@ChenPi
推荐专栏1: 《C++》✨✨✨
推荐专栏2: 《 Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨
推荐专栏3: 《 链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
本篇简介 : 链表数据插入之尾插法
✨ 只有我努力了 才有机会接触成功✨
链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。说到这里你应该就明白了,链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。
作为有强大功能的链表,对他的操作当然有许多,比如:
- 链表的创建
- 链表的链表的遍历打印数据
- 链表里面的结构体数据的修改
- 链表节点的删除
- 链表插入新节点
- 链表的数据排序
- 链表的反序
- 清空链表的元素
- 求链表的长度等
在前面几章,我们学习了
- 链表的创建
- 链表的链表的遍历打印数据
- 链表里面的结构体数据的修改
- 求链表的长度等
- 还有链表结尾插入数据节点,非指定节点
- 链表指定节点后方插入数据
今天我们学链表头的前方插入数据
今天任务如同所示,我们需要创建一个新的头节点,然后让新的头节点指向旧的头节点, 然后让新的节点成为头节点
所以我们要定义个函数frontInsertDataLink,然后我希望的是,我把头节点的地址以及要插入的数据传进来后创建一个新的头节点,头节点的数据等于我传进来的数据
函数的返回值的话
我希望的是要返回头节点的地址
函数大致如下
我们来解读一下
第23行就是函数体的大概样子了
返回值为struct Link*的 结构体指针,用于放回头节点的地址
参数1是头节点的地址了,参数2就是新节点的数据内容了
第25行:创建1个结构体指针,名为prev,指向头文件
第26-28行:创建1个新的头节点,然后让头节点的data = data
然后让新的头节点的next指向旧的头节点就可以了
我们看一下主函数,看一下这个函数怎么用的
红箭头那里就是该函数的使用了
红框那里则是获取头节点,我们也顺便看一下这么实现的
我们先看一下函数体
函数名getHead,返回值为一个结构体指针,用于返回头节点的地址,有一个参数,此参数就是头节点的数据了
第34到36就是给头节点赋值了
最后返回该节点的地址
我们创建一个新节点接收它就可以
编译完我们看一下结果,没问题,我们先创建了头节点,数据为3
后面从头节点前方再创建新的节点,数据为5
所以打印出来
5 3,正确
#include
#include
#include
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;
}
写到这,好像发现之前写的代码出了点小问题,就是没有检查索引有没有超出范围
这个代码是头插法的最终的最终版本了,
第58行到62行是检测NodeIndex索引有没有越界
第63行到67行就是当索引Nodeindex = 1的时候,就调用前面刚写好的链表头插入新节点函数
68到80行则是链表遍历,根据索引值的多少,找都那个节点,并在索引值对应的节点前插入新节点
我们代码测试一下,索引值写为-1,就是找-1个节点,按道理是没有的,所以应该打印出错信息
打印提示越界了,那我们换个正常的试试,比如1
然后就在第一个节点前插入了新节点
没问题,测试代码如下
#include
#include
#include
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;
}
对您有帮助的话记得点赞加关注
如果有说的不对的欢迎指正