目录
前言 编辑
01 链表指定节点后插入数据(根据节点号插入)
测试代码
02 链表指定节点后插入数据(根据节点的数据插入)
尾插法的代码
前言
🎬 个人主页:@ChenPi
🐻推荐专栏1: 《C++》✨✨✨
🔥 推荐专栏2: 《 Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨
📝推荐专栏3: 《 链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
🍉本篇简介 : 链表数据插入之尾插法
✨ 只有我努力了 才有机会接触成功✨
链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。说到这里你应该就明白了,链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。
作为有强大功能的链表,对他的操作当然有许多,比如:
- 链表的创建
- 链表的链表的遍历打印数据
- 链表里面的结构体数据的修改
- 链表节点的删除
- 链表插入新节点
- 链表的数据排序
- 链表的反序
- 清空链表的元素
- 求链表的长度等
在前面几章,我们学习了
- 链表的创建
- 链表的链表的遍历打印数据
- 链表里面的结构体数据的修改
- 求链表的长度等
- 还有链表结尾插入数据节点,非指定节点
01 链表指定节点后插入数据(根据节点号插入)
我们要在指定的节点后插入数据,提醒一下,这里的节点是指的第几个节点,不是按数值来查
我们定义个函数tailInsertNodeLinkList(),函数的返回值尾int,因为我们需要返回标志位
用于查看是否错误
这个函数有三个参数,
参数1位一个结构体的指针,因为要传如头节点,
参数2为一个整形数,用于找到第几个节点
参数3为一个整形数,为节点的数据
根据需求,我们可以知道函数体的大致模样了
int tailInsertNodeLinkList(struct Link * head,const int size,const int data)
{
}
然后我们根据需求将代码补全
我们看代码进行分析一下
第109行,定义一个结构体指针,指向了链表头,原因是,操作链表的时候最好不要直接操作链表
第110行,定义了一个整形变量cnt,用于遍历时记录目前是第几节点
第110 - 113行就是定义了一个新节点,并初始化
第114 - 124行就是链表的遍历了
第116行,if语句进行判断,如果当前节点 = 目标节点,就进入if语句
里面到底做了什么事呢?
大致就是这样,先让新的节点的next = prev的next,
在将prev的next指向new
就是这样,很简单
我们代码测试一下
链表开始的时候只有头节点,我们先用上一章的函数,尾插法增长了链表,我这里输入了8和5
那按道理链表现在又了三个数1 8 2
现在我要用 这一章的代码在第二个节点插入数据5
所以最后打印的时候是1 8 5 2
没有问题
测试代码
#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 tailInsertLinkList(struct Link * head,int data)
{
if(NULL == head)
{
return -1;
}
struct Link *prev = head;
struct Link *new = (struct Link*)malloc(sizeof(struct Link ));
new->data = data;
new->next = NULL;
while (NULL != prev)
{
if(NULL == prev->next)
{
prev->next = new;
return 1;
}
prev = prev->next;
}
return -1;
}
int tailInsertLinkListPro(struct Link * head,const int size)
{
int *bufData = (int*)malloc(sizeof(int)*size);
for(int i = 0; i < size; i++)
{
scanf("%d", bufData+i);
tailInsertLinkList(head,bufData[i]);
}
}
/*参数1 结构体指针头节点的地址,参数2第几个节点后插入数据,参数3要插入的数据*/
int tailInsertNodeLinkList(struct Link * head,const int size,const int data)
{
struct Link *prev = head;
int cnt = 1;
struct Link *new = (struct Link*)malloc(sizeof(struct Link ));
new->next = NULL;
new->data = data;
while (NULL != prev)
{
if(cnt == size)
{
new->next = prev->next;
prev->next = new;
return 1;
}
cnt++;
prev = prev->next;
}
return -1;
}
int main()
{
struct Link head = {1,NULL};
int size = 0;
puts("请输入你要在链表尾部插入的数据数目");
scanf("%d",&size);
printf("请按要求输入%d个数据\n",size);
tailInsertLinkListPro(&head,size);
tailInsertNodeLinkList(&head,2,5);
PrintLink(&head);
return 0;
}
02 链表指定节点后插入数据(根据节点的数据插入)
刚写完根据目标节点数进行节点插入,现在我们写一个根据节点的数据进行插入,如果于于目标数据一致,则在其后插入一个新节点
如果成功返回目标目前节点号
失败返回-1
这个代码其实也很简单,和前面的长的差不多,就是找的目标数据后,进行新节点插入
int tailDtaNodeLinkList(struct Link *head,const int targetData,const int data)
{
struct Link *prev = head;
struct Link *new = (struct Link*)malloc(sizeof(struct Link));
new->data = data;
new->next = NULL;
int cnt = 1;
while (prev!= NULL)
{
if(prev->data == targetData)
{
new->next = prev->next;
prev->next = new;
return cnt;
}
cnt++;
prev = prev->next;
}
puts("数据插入失败");
return -1;
}
函数的参数1为头节点的地址,参数2为目标节点的数据,参数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");
}
/*获取链表的节点数*/
int GetLinkNum(struct Link *head)
{
struct Link *prev = head;
int count = 0;
while (prev != NULL)
{
count++;
prev = prev->next;
}
return count;
}
/* 查找链表中的数据,只能找到一个,且不知道节点数*/
int findLinkData(struct Link *head,int data)
{
struct Link *prev = head;
while (prev!= NULL)
{
if (prev->data == data)
{
return 1;
}
prev = prev->next;
}
return 0;
}
/* 在链表中查找需要的数据,如果有,打印节点号和数据*/
void FindLinkDataPro(struct Link *head,int data)
{
int count = 0; //遍历记录节点号
int NumFd =0; // Number数据的索引
int Number[32] = {0};
struct Link *prev = head;
while (prev!= NULL)
{
if(prev->data == data)
{
Number[NumFd++] = count;
}
count++;
prev = prev->next;
}
for(int i = 0; i < NumFd; i++)
{
printf("节点号:%d 查找的数据%d\n",Number[i]+1,data);
}
}
/*尾部顺序插入形成链表*/
int tailInsertLinkList(struct Link * head,int data)
{
if(NULL == head)
{
return -1;
}
struct Link *prev = head;
struct Link *new = (struct Link*)malloc(sizeof(struct Link ));
new->data = data;
new->next = NULL;
while (NULL != prev)
{
if(NULL == prev->next)
{
prev->next = new;
return 1;
}
prev = prev->next;
}
return -1;
}
int tailInsertLinkListPro(struct Link * head,const int size)
{
int *bufData = (int*)malloc(sizeof(int)*size);
for(int i = 0; i < size; i++)
{
scanf("%d", bufData+i);
tailInsertLinkList(head,bufData[i]);
}
}
/*参数1 结构体指针头节点的地址,参数2第几个节点后插入数据,参数3要插入的数据*/
int tailInsertNodeLinkList(struct Link * head,const int size,const int data)
{
struct Link *prev = head;
int cnt = 1;
struct Link *new = (struct Link*)malloc(sizeof(struct Link ));
new->next = NULL;
new->data = data;
while (NULL != prev)
{
if(cnt == size)
{
new->next = prev->next;
prev->next = new;
return 1;
}
cnt++;
prev = prev->next;
}
return -1;
}
int tailDtaNodeLinkList(struct Link *head,const int targetData,const int data)
{
struct Link *prev = head;
struct Link *new = (struct Link*)malloc(sizeof(struct Link));
new->data = data;
new->next = NULL;
int cnt = 1;
while (prev!= NULL)
{
if(prev->data == targetData)
{
new->next = prev->next;
prev->next = new;
return cnt;
}
cnt++;
prev = prev->next;
}
puts("数据插入失败");
return -1;
}
int main()
{
struct Link head = {1,NULL};
int size = 0;
puts("请输入你要在链表尾部插入的数据数目");
scanf("%d",&size);
printf("请按要求输入%d个数据\n",size);
tailInsertLinkListPro(&head,size);
tailDtaNodeLinkList(&head,2,5);
PrintLink(&head);
return 0;
}
好了,尾插法就先讲到这里了,如果有什么不太理解或者我写错的,欢迎来一起讨论