C语言中的链表

C语言链表

链表的概念就是能通过指针访问非连续的地址里面的数据,个人理解

代码:

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

struct test
{
  int data;
  struct test *next;

};

int main()
{
//接触链表

//数组里面的地址是连续的,找到首个地址就能打印出完整的数组里面的东西
int arry[]={1,2,3,4,5,6,7,8,9,10};
int len=sizeof(arry)/sizeof(arry[0]);//kongzhixiabiao
int i;//shuzhuxiabao
for(i=0;i<len;i++)
{

printf("%d\t",arry[i]);//dayinshuzu1-10;
}
  printf("\n");
//链表使用的例子,三个完全分开的结构体,通过链表和指针访问里面的数据
   struct test t1={1,NULL};
   struct test t2={2,NULL};
   struct test t3={3,NULL};//san ge jie gou ti zhi zhen
    //t1里面的指针指向了t2结构体的地址
    t1.next=&t2;//t1 de zhi zhen qu dao t2jieguoti dizhi
    //t2里面的指针指向了t3结构体的地址
    t2.next=&t3;//t2 he t1 yi yang qu dao zhi zhen
    printf("%d %d %d",t1.data,t1.next->data,t1.next->next->data);//通过t1结构体里面的指针间接访问,每个结构体里面的data,然后打印出来
    //而t1里面的结构体指针就是链表的头
return 0;
}

链表的动态添加和动态遍历

通过循环来控制链表
代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct test
{
  int data;
  struct test *next;
   
}stu;

void printlink(stu*p,stu t2,stu t3,stu t4)
{
   stu*p2=p;//保留一个首地址
   p2->next=&t2;//取到结构体t2的地址
   t2.next=&t3;//取到结构体t3的地址
   t3.next=&t4;//取到结构体t4的地址

   while(p2!=NULL)//判断指针不等于空指针,否则退出循环
    {
      if(p2!=NULL)//当指针不是空指针执行下面语句
      {
         
         printf("%d ",p2->data);//先打印一次链表头的data,也就是t1里data的值
           p2=p2->next;//进行指针偏移,是指针指向t2结构体,再次输出t2里面的值,直到不满足if和while里面的条件退出循环
      }
     }
   printf("\n");
}
int main()
{
   stu t1={1,NULL};
   stu t2={2,NULL};
   stu t3={3,NULL};
   stu t4={4,NULL};

   printlink(&t1,t2,t3,t4);//把结构体t1的地址,和另外三个结构体当作实际参数进行传递

return 0;
}

统计链表节点个数及链表查找

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct test
{
  int data;
  struct test*next;
}stu;


void printlink(stu *t1)//使用链表访问结构体的函数
{
    stu*p=t1;
    while(p!=NULL)
     {
         printf("%d ",p->data);
         p=p->next;
     }
   putchar('\n');
}

int jiedian2(stu *p)//返回值为节点数的函数
{
  int cmd=0;
  while(p!=NULL)
    {
    cmd++;//条件满足+1;
    p=p->next;//指针进行偏移,条件不满足退出循环
    }
  return cmd;
}

int jiedian(stu*p,int ret)//通过ret值来看你想返回的节点数是多少1-5.超过5就返回0了
{
    while(p!=NULL)
      {
      if(p->data==ret)
         {
         return 1;
         }
         p=p->next;
      }
    return 0;
}

int main()
{

  stu t1={1,NULL};
  stu t2={2,NULL};
  stu t3={3,NULL};
  stu t4={4,NULL};
  stu t5={5,NULL};
  
  t1.next=&t2;
  t2.next=&t3;
  t3.next=&t4;
  t4.next=&t5; 
  printlink(&t1);
  
  int ret;


ret=jiedian2(&t1);//通过这个函数返回值来看链表节点数
printf("lianbiaojiedianshi=%d\n",ret);
ret=jiedian(&t1,3);//找到第三个节点数
//printf("lianbiaodisangejiedian,%d\n",ret);
if(ret==1)
{
printf("have 3\n");
}
else{
printf("no 3\n");
}
ret=jiedian(&t1,8);//当节点数超过后的返回值是否正确
if(ret==1)
{
 printf("have 8\n");
}
else{
   printf("no 8\n");
    }
return 0;
}

运行结果:
在这里插入图片描述

在一个链表中插入一个新的节点

代码:

typedef struct test
{
  int data;
  struct test*next;//结构体指针
}stu;//使用关键字tpyedef
void printstu(stu*p)
{
   stu*p2=p;//保留一个原来的地址
   while(p2!=NULL)//判断结构体的指针不是空的
   {
      printf("%d\t",p2->data);//打印第一个结构体的值
       p2=p2->next;//使其指针指向下个结构体的地址,直到条件不满足退出循环
   }
   putchar('\n');
}
int change(stu*p,int data,stu*new)
{
stu *p2=p;//保留一个地址
while(p2!==NULL)//判断循环条件是否满足不等于空指针
{
  if(p2->data==data)//如果条件满足=3,在结构体后面插入新的节点
  {
      new->next=p2->next;//新节点的指针指向下一个原本要指向节点的地址
      new=p2->next;//新节点的地址被第三个节点指针指向
  }
  p2=p2->next;//指针偏移
}

return 0;
}
int main()
{
//给每个结构体赋值
stu t1={1,NULL};
stu t2={2,NULL};
stu t3={3,NULL};
stu t4={4,NULL};
stu t5={5,NULL};
t1.next=&t2;
t2.next=&t3;
t3.next=&t4;
t4.next=&t5;//每个结构体的指针指向下一个结构体的地址,
//定义一个打印结构体值的函数,使用链表
printstu(&t1);//传递结构体t1的地址
//插入一个新的节点,在第三个节点后面
stu new={100,NULL};//一个新的节点
change(&t1,3,&new);
//重新打印一遍结构体的值
printfstu(&t1);
return 0;
}

可以通过改变change(&t1,3,&new);函数里面的常量3选择你想在那个节点插入新的节点1-5都可以
运行结果:
在这里插入图片描述

链表:从指定链表的前方插入一个新的节点

从链表的头插入

代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
tepydef struct test
{
int data;
struct test*next;
}stu;
void printstu(stu*p)
{
stu*p2=p;//保留一个地址
 while(p2!=NULL)
 {
 printf("%d\t",p2->data);
 p2=p2-next;//改变地址
 }
printf("\n");
}
stu *change(stu*p,int data,stu*new)
{
     stu*p2=p;//保留一个地址
     if(p2->data==data)//如果链表头的data是1执行插入
     {
     new->next=p2;//新的节点指向链表头t1的地址
     }
     return new;//最后返回新节点的地址
}
int main()
{
stu t1={1,NULL};
stu t2={2,NULL};
stu t3={3,NULL};
stu t4={4,NULL};
stu t5={5,NULL};//结构体初始化
stu new={100,NULL};//新的节点
stu *res=NULL;
res=&t1;//取到结构体t1的地址

t1.next=&t2;
t2.next=&t3;
t3.next=&t4;
t4.next=&t5;
printstu(res);//打印结构体的里面的data
//在链表头插入一个新的节点
res=change(&t1,1,&new);
//重新打印一遍
printstu(res);//新的节点当链表头进行打印
return 0;
}

运行结果:
在这里插入图片描述

链表中间插入一个新的节点

例子:在第二个节点插入一个新的节点
代码:

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

typedef struct test
{
int data;
struct test *next;
}stu;//定义了一个结构体包含int类型和结构体指针
void printstu(stu*p)
{
stu*p2=p;
while(p2!=NULL)
{
printf("%d\t",p2->data);//先打印第一结构体的data
p2=p2->next;//指向下一个地址,直到循环退出
}
printf("\n");
}
stu* change(stu*p,int data,stu*new)
{
stu*p2=p;
//如果想在链表头前面插入节点
if(p2->data==data)
{
  new->next=p2;//新的节点指向第一个链表头
  return new;//返回新链表头的地址就可以了
}
//在第二个或者后面几个之前插入
while(p2-next!=NULL)//建立循环,指向下一个节点不是空指针
{
if(p2->next->data==data)//根据你想要在那个节点前面插入判断
{
new->next=p2->next;//新的节点指向第二个节点
p2-next=new;//第一个节点指向新的节点
return p;//返回原来节点的地址
}
p2=p2->next;
}
return p;//没找到也返回原来的地址
}
int main()
{
stu *res=NULL;//结构体指针
stu t1={1,NULL};
stu t2={2,NULL};
stu t3={3,NULL};
stu t4={4,NULL};
stu t5={5,NULL};//结构体的初始化
res=&t1;
t1.next=&t2;
t2.next=&t3;
t3.next=&t4;
t4.next=&t5;//结构体链表链接每个结构体
//打印每个结构体里面的数
printstu(res);
//在第二个节点前面插入一个新的节点(结构体)
stu new={10,NULL};//新的节点
//可以通过输入1-5来当作参数,我比较懒
res=change(&t1,2,&new);//改变链条的函数
//重新打印插入新的节点的链表
printstu(res);
return 0;
}

运行结果:
在这里插入图片描述

删除链表头和中间某个节点

代码:

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

struct test
{
int data;
struct test*next;
}stu;//结构体里面包含整数变量和结构体指针
void prinlink(stu*p)
{
stu *p2=p;
while(p2!=NULL)
{
    printf("%d\t",p2->data);
    p2=p2->next;//指针指向下一个地址直到退出循环
}
printf("\n");//换行
}
stu *change(stu*p,int data)
{
stu*p2=p;//保留一个原始地址
//如果是删除第一个节点,直接返回第二个节点的地址
if(p2->data==data)
{
p=p2->next;//直接把第二个节点的地址赋值给到第一个节点
return p;
}
//如果不是第一个节点
while(p2->next!=NULL)
{
if(p2->next->data==data)
{//找到节点值后把后面节点给到当前节点,当前节点就不会执行了
p2->next=p2-next->next;
return p;
}
P2=P2->next;
}
return p;//如果超输入的数字超过节点数,直接返回原来节点
}
int main()
{
     stu t1={1,NULL};
     stu t2={2,NULL};
     stu t3={3,NULL};
     stu t4={4,NULL};
     stu t5={5,NULL};
     stu*res=NULL;//结构体指针
     res=&t1;//指向t1的地址
      //打印链表的值
      prinlink(res);
//判断你要删除的节点值
int a;
printf("请问你要删除那个节点的值\n");
scanf("%d"&a);
    res=change(res,a);
//再次打印你删除的节点值
prinlink(res);
return 0;
}

运行结果:
在这里插入图片描述

头插法,malloc动态创建空间

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct test
{
int data;
struct test *next;
}stu;

stu* change(stu*p)
{
stu *new=NULL;//一个新的结构体指针
while(1)//建立一个循环,动态开辟空间
{
new=(stu*)malloc(sizeof(stu));//开辟新的节点
printf("输入新的节点data的值\n");
scanf("%d",&(new->data));
if(new->data==0)
{
printf("0,结束循环的条件");
return p;//直接返回地址
}
if(p==NULL)//第一次进来让p指针指向新开辟的空间
{
p=new;//指针指向了新开辟空间的地址
}
esle{
new->next=p;//新开辟的空间指向刚才开辟的空间地址
p=new;//再让p重新指向新的开辟的空间
}
}
return p;
}
void prinlink(stu*p)
{
stu *p2=p;
while(p2!=NULL)
{
printf("%d\t",p2->data);//先打印链表头的数据,
p2=p2->next;//再指向第二个节点,
}
}
int main()
{
//在链表头插入一个新的节点
stu*res=NULL;//结构体的空指针,
//开辟空间的函数
res=change(res);//返回的是链表头
//打印链表的值
prinlink(res);
return 0;
}

运行结果:新的节点永远处于第一个链表头的位置
在这里插入图片描述

头插法第二种写法,分开来写

代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct test
{
   int data;
   struct test*next;//结构体指针
}stu;

stu* newspace(stu*p,stu*new)
{
  if(p==NULL)
  {
  p=new;//第一次让main函数里面指针指向新开辟的空间的位置
  }
else{
  new->next=p;//新开辟的空间指向链表头
  p=new;//重新把p指向新开辟的空间
}
return p;//返回结构体的地址
}
stu* change(stu*p)
{
   stu*new;//定义一个结构体指针
while(1)//建立一个循环,不停的开辟空间
{
new=(stu*)malloc(sizeof(stu));
printf("输入新开辟空间的数\n");
scanf("%d",&new->data);
if(new->data==0)
{
printf("停止开辟空间\n");
free(new);//把开辟的空间给悬挂
return p;//直接返回结构体指针
}
else{
p=newspace(p,new);//形成链表的函数
}
}
}

void printlink(stu*p)
{
stu*p2=p;
while(p2!=NULL)
{
  printf("%d\t",p2->data);
  p2=p2->next;
}
printf("\n");
}
int main()
{
  stu *res=NULL;//结构体的空指针
  res=change(res);//开辟空间的函数
  printlink(res);
  //如果想单独插入一个新的节点,直接调用函数newspace直接插入就行
  stu t1={1000,NULL};
  res=newspace(res,&t1);//直接传递新节点的地址
  printlink(res);
return 0;
}

运行结果:新节点最后输入的是9
在这里插入图片描述

尾插法,把新界点插入到尾巴

代码:

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

typedef struct test
{
int data;
struct test*next;
}stu;

stu* newspace(stu*p,stu*new)
{
 stu*p2;//保留一个首地址
  if(p2==NULL)//第一次进来p是空的把新开辟空间的地址给到p
  {
  p=new;
  return p;//返回p的地址
  }
  if(p2->next!=NULL)//判断下一个地址是否为空
  {
  p2=p2->next;//不为空地址就是往后偏移
  }
  p2->next=new;//偏移后p2的指针本来是空的指向新开辟的节点
  return p;//在返回链表头的地址
}
stu* change(stu*p)
{
  stu*new;
  while(1)
{
  new=(stu*)malloc(sizeof(stu));//开辟空间
  printf("输入每个开辟空间的值\n");
  scanf("%d",&new->data);
  if(new->data==0)
  {
  printf("停止开辟空间\n");
  free(new);
  return p;
  }else{
    p=newspace(p,new);
      }
}
}
void printlink(stu*p)
{
stu*p2=p;
while(p2!=NULL)
{
  printf("%d\t",p2->data)
  p2=p2->next;
}
putchar('\n');
}

int main()
{
stu*res=NULL;
res=change(res);//开辟空间的函数
printlink(res);//打印链表每个节点的值
//可以选择直接插入一个链表
stu t1={2000,NULL};
res=newspace(res,&t1);
printlink(res);
return 0
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言链表是一种常用的数据结构,用于存储和操作数据。下面是一个简单的示例,展示了如何在C语言使用链表: ```c #include <stdio.h> #include <stdlib.h> // 定义链表节点结构 struct Node { int data; struct Node* next; }; // 在链表末尾插入新节点 void insert(struct Node** head, int data) { // 创建新节点 struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; // 如果链表为空,将新节点作为头节点 if (*head == NULL) { *head = newNode; return; } // 找到链表末尾的节点 struct Node* current = *head; while (current->next != NULL) { current = current->next; } // 将新节点插入到末尾 current->next = newNode; } // 打印链表的所有节点 void printList(struct Node* head) { struct Node* current = head; while (current != NULL) { printf("%d ", current->data); current = current->next; } printf("\n"); } // 释放链表内存 void freeList(struct Node* head) { struct Node* current = head; while (current != NULL) { struct Node* temp = current; current = current->next; free(temp); } } int main() { // 创建一个空链表 struct Node* head = NULL; // 在链表末尾插入节点 insert(&head, 1); insert(&head, 2); insert(&head, 3); // 打印链表 printf("链表的节点:"); printList(head); // 释放链表内存 freeList(head); return 0; } ``` 这个示例演示了如何定义链表节点结构,插入新节点,打印链表的所有节点,并释放链表内存。你可以根据自己的需求修改和扩展这个示例。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值