创建链表(并初始化)
#include <stdio.h>
#include <stdlib.h>
struct link // 定义链表的类型
{
int data; // 数据区
struct link *next; // 地址区用来存放下一个元素的地址
};
// 函数声明
void display(struct link * p); // 遍历链表
int select(struct link * p,int n); // 链表中查找元素函数
struct link* gengai(struct link* p,int add,int num); // 链表中修改某个节点函数
struct link* del(struct link * p,int add); // 链表中删除某个节点函数
struct link* insert(struct link * p,int data,int add); // 链表中插入某个节点
int main( )
{
int i;
struct link *p = (struct link *) malloc(sizeof(struct link)); // 创建一个头结点 就是指向链表的第一个元素
struct link *temp = p; // 声明一个指针指向头结点,用于遍历链表
// 创建链表 并进行初始化
for (i = 0; i < 5; i++)
{
struct link *a = (struct link *) malloc(sizeof(struct link)); // 开辟第一个link的空间用于存储数据
a->data = i; // 初始话第一个空间 数据区
a->next = NULL; // 将第一个元素的地址区赋值为空
// 此时的temp其实就是p的地址(也就是头节点)将头节点的地址区存a的地址(就是把第一个元素的地址存到了头节点的地址区,这样就可以通过头节点找到第一个元素了)
temp->next = a;
temp = temp->next; // temp = temp->next; 就是这个意思 temp = a(就是把第一个元素的地址给temp,下次进来temp就是第一个元素的地址了)
}
return 0;
}
遍历链表
void display(struct link * p)
{
struct link *t = p->next; // 因为p节点是我们用来指向链表的第一个元素的,所以现在在创建一个struct link* t来找到第一个元素的地址
while (t != NULL) // 链表的最后一个节点的地址是NULL 所以遇到NULL 就会结束
{
printf("%d ", t->data); // 遍历数据区
t = t->next; // 每次往后找一个
}
}
链表中查找元素
int select(struct link * p,int n)
{
// 链表中查找某数是否存在(其实和遍历差不多)
int i=1;
struct link *t = p->next; //创建临时结点t 因为p是链表头节点,p的地址区存着第一个链表第一个元素地址
while (t!=NULL)
{
if(t->data==n)
return i;
t = t->next;
i++;
}
return -1; // 表示没找到
}
链表中更改某结点的数据域
struct link* gengai(struct link* p,int add,int num)
{
//链表中更改某结点的数据域
int i;
struct link * temp=p->next; // 创建临时结点temp 因为p是链表头节点,p的地址区存着第一个链表第一个元素地址
// 遍历到被删除结点
for(i=1; i<add; i++) {
temp=temp->next;
}
temp->data=num; // 找到被删除的节点的数据区 就需要修改的值赋值给他,
return p; // 返回头节点地址
}
从链表中删除节点
struct link* del(struct link * p,int add)
{
// 从链表中删除节点
int i;
struct link * temp=p; // 创建临时结点temp 注意:此时p是头节点不是链表第一个元素
// temp指向被删除结点的上一个结点
for (i=1; i<add; i++) {
temp=temp->next;
}
// 把被删除结点存起来,以防丢失
// 因为temp是被删除节点的 上一个节点,所以temp->next就是被删除的节点
struct link * del=temp->next;
// 把被删除的那个节点里面存他的下一个地址
temp->next=temp->next->next; // temp->next(被删除的节点->next就是他的下一个地址) ->next
free(del); // 手动释放该结点,防止内存泄漏
return p; // 返回头节点地址
}
向链表中插入结点
struct link* insert(struct link * p,int data,int add)
{
// 向链表中插入结点
// 第一步找到需要插入的节点的前一个元素
// 第二步把前一个地址的地址区存 插入的节点的地址
// 第三步把插入的节点的地址区存 (前一个地址区里面存的地址)这句重点
int i;
struct link * temp=p; // 创建临时结点temp 注意:此时p是头节点不是链表第一个元素
for(i=1;i<add;i++)
{
temp = temp->next;
}
struct link * c=(struct link*)malloc(sizeof(struct link)); // 创建插入的节点
c->data = data; // 将需要插入的数存到节点数据区中
c->next=temp->next; // 将需要插入的节点的地址区存temp的后一个地址所以就是temp->next
temp->next = c; // temp也就是前一个节点里面存c的地址
return p; // 返回头节点地址
}
转载:https://blog.csdn.net/weixin_45715405/article/details/116721453
查看评论