创建链表(并初始化)

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

struct link   // 定义链表的类型
{
int data;// 数据区
struct link *next;// 地址区用来存放下一个元素的地址
};

// 函数声明
voiddisplay(struct link * p);// 遍历链表
intselect(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);// 链表中插入某个节点

intmain( )
{
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就是第一个元素的地址了)
}
return0;
}

遍历链表

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;// 返回头节点地址
}