链表源码汇总

简介: 文章目录 链表的简易创建及输出数据 链表的遍历源码 链表的统计与查找 链表后插法

文章目录


链表的简易创建及输出数据


#include<stdio.h>
struct test
{
        int data;
        struct test *next;
};
int main()
{
        struct test t1={1,NULL};
        struct test t2={2,NULL};
        struct test t3={3,NULL};
        t1.next = &t2;
        t2.next = &t3;
        printf("%d %d %d\n",t1.data,t1.next->data,t1.next->next->data);
        return 0;
}          


链表的遍历源码

#include<stdio.h>
struct test//定义一个结构体
{
  int data;//定义数据
  struct test *next;//定义结构体下一个
};
void printlink(struct test *head)//定义无类型输出(定义结构体指针头)
{
  struct test *point;//定义结构体指向
  point=head;//将头给指向
  while(point !=NULL)//当指向不等于空
  {
    printf("%d",point->data);//输出结构体指针指向的数据
    point = point->next;//结构体指针指向数据的下一个给指向
  }   
  putchar('\n');//输出下一行
}
int main()
{
  int i;//定义i
  int array[]={1,2,3};//定义数组array并传参123
  for(i=0;i<sizeof(array)/sizeof(array[0]);i++)//i=0;i小于12/3,i++
  {
    printf(" 数组中的遍历%d ",array[i]);//输出
  }
  putchar('\n');
  struct test t1 ={1,NULL};//定义结构体节点t1,并传参1,NULL给t1
  struct test t2 ={2,NULL};//同上
  struct test t3 ={3,NULL};
  struct test t4 ={4,NULL};
  struct test t5 ={5,NULL};
  struct test t6 ={6,NULL};
  struct test t7 ={7,NULL};
  t1.next =&t2;//将节点t1的下一个与t2地址相连,达到链接的目的
  t2.next =&t3;//同上
  t3.next =&t4;
  t4.next =&t5;
  t5.next =&t6;
  t6.next =&t7;
  printf("use t1 print three nums\n");
//  printf("%d %d %d %d\n",t1.data,t1.next->data,t1.next->next->data,t1.next->next->next->data);//很土的方法输出
  printlink(&t1);//调用printlink
  return 0;
}

链表的统计与查找


#include<stdio.h>
  struct test
  {
    int data;
    struct test *next;
  };
  void printlink(struct test *head)//定义输出函数
  {
    struct test *point;//定义结构体指针变量
    point=head;//将头给新的              (详细见上篇文章) 
    while(point !=NULL)
    {
      printf("%d",point->data);
      point = point->next;
    }   
    putchar('\n');
  }
  int getlinktotalnodenum(struct test *head)//定义一个函数,计算链表节点个数
  {
    int cnt = 0;//定义cnt并付出值0
    while(head!=NULL)//当head不为空时
    {
      cnt++;//+1
      head = head->next;//当传参的值等于链表中的值
    }
    return cnt;//返回cnt
  }
  int searchlink(struct test *head,int data)//查找链表中的值
  {
    while(head !=NULL)///当头不为空时
    {
      if(head->data==data)//如果头的数值等于传参的属实
      { 
      return 1;//返回1
      }
      head=head->next;//遍历下一个   即将头的下一个给头
    }
    return 0;//返回0
  }
int main()
{
  int i;
  int array[]={1,2,3};
  for(i=0;i<sizeof(array)/sizeof(array[0]);i++)
  {
    printf(" %d ",array[i]);
  }
  putchar('\n');
  struct test t1 ={1,NULL};
  struct test t2 ={2,NULL};
  struct test t3 ={3,NULL};
  struct test t4 ={4,NULL};
  struct test t5 ={5,NULL};
  struct test t6 ={6,NULL};
  struct test t7 ={7,NULL};
  t1.next =&t2;
  t2.next =&t3;
  t3.next =&t4;
  t4.next =&t5;
  t5.next =&t6;
  t6.next =&t7;
  printf("use t1 print three nums\n");
//  printf("%d %d %d %d\n",t1.data,t1.next->data,t1.next->next->data,t1.next->next->next->data);
  printlink(&t1);//调用输出函数
  int ret = getlinktotalnodenum(&t1);//调用函数,将返回值给ret
  printf("total num = %d\n",ret);//输出ret的值,即节点个数
  ret = searchlink(&t1,1);//查找1并传参
  if(ret == 0)//如果返回值为0
  {
    printf("no 1\n");//输出表示没有
  }
  else
  {
    printf("have 1\n");//除非就是有
  }
  ret =searchlink(&t1,8);//查找8并传参
  if(ret==0)
  {
    printf("no 8\n");
  }
  else
  {
    printf("have 8\n");
  }
  return 0;
}

链表后插法


#include<stdio.h>
struct test
{
  int data;
  struct test *next;
};
int insertfrombehind(struct test *head,int data,struct test *new)//定义函数后插法,并定义指针头,局部变量数据,新节点
{
  struct test *p =head;//定义指针p将头传给
  while (p!=NULL)//当指针p不等于空时
  {
    if(p->data == data)//如果指针的数据等于传参的数据
    {
      new->next=p->next;//将原本指针p的下一个给新的下一个 也就是让新节点new的下一个指向原本老节点p的下一个
      p->next=new;//将老节点p指向新节点new
      return 1;//返回1
    }
    p=p->next;//遍历需要插入的节点,p的下一个给p,即后移
  }
  return 0;//返回0,相当于没找到
}
void printlink(struct test *head)
{
  struct test *point;
  point=head;
  while(point !=NULL)
  {
    printf("%d",point->data);
    point = point->next;
  }   
  putchar('\n');
}
int getlinktotalnodenum(struct test *head)
{
  int cnt = 0;
  struct test *p =head;
  while(p!=NULL)
  {
    cnt++;
    p = p->next;
  }
  return cnt;
}
int searchlink(struct test *head,int data)
{
  while(head !=NULL)
  {
    if(head->data==data)
    { 
    return 1;
    }
    head=head->next;
  }
  return 0;
}
int main()
{
  int i;
  int array[]={1,2,3};
  for(i=0;i<sizeof(array)/sizeof(array[0]);i++)
  {
    printf(" %d ",array[i]);
  }
  putchar('\n');
  struct test t1 ={1,NULL};
  struct test t2 ={2,NULL};
  struct test t3 ={3,NULL};
  struct test t4 ={4,NULL};
  struct test t5 ={5,NULL};
  struct test t6 ={6,NULL};
  struct test t7 ={7,NULL};
  t1.next =&t2;
  t2.next =&t3;
  t3.next =&t4;
  t4.next =&t5;
  t5.next =&t6;
  t6.next =&t7;
  struct test new = {100,NULL};
  printf("use t1 print three nums\n");
//  printf("%d %d %d %d\n",t1.data,t1.next->data,t1.next->next->data,t1.next->next->next->data);
  printlink(&t1);
  puts("after insert behind:\n");//打印在后面插入
  insertfrombehind(&t1,3,&new);//调用后插函数,并传参3给函数,和新的节点
  printlink(&t1);打印输出
/*  int ret = getlinktotalnodenum(&t1);
  printf("total num = %d\n",ret);
  ret = searchlink(&t1,1);
  if(ret == 0)
  {
    printf("no 1\n");
  }
  else
  {
    printf("have 1\n");
  }
  ret =searchlink(&t1,8);
  if(ret==0)
  {
    printf("no 8\n");
  }
  else
  {
    printf("have 8\n");
  }
*/
  return 0;
}

链表前插法之插链表头


#include <stdio.h>
struct test
{
  int data;
  struct test *next;
};
struct test* insertfromfor(struct test *head,int data,struct test *new)//定义结构体函数前插法插头
{
  struct test *p =head;//定义局部结构体指针变量p,并将头给p
  if(p->data==data)//如果插入的地方是正好是传参的值
  {
    new->next=head;//将新节点的下一个链接当前的上头
    return new;//将新节点返回
  }
}
void printlink(struct test *head)//遍历打印输出
{
  struct test *point;
  point=head;
  while(point !=NULL)
  {
    printf("%d ",point->data);
    point = point->next;
  }   
  putchar('\n');
}
int main()
{
  struct test *head = NULL;//定义结构体指针头,并传参空
  putchar('\n');
  struct test t1 ={1,NULL};
  struct test t2 ={2,NULL};
  struct test t3 ={3,NULL};
  struct test t4 ={4,NULL};
  struct test t5 ={5,NULL};
  struct test t6 ={6,NULL};
  struct test t7 ={7,NULL};
  t1.next =&t2;
  t2.next =&t3;
  t3.next =&t4;
  t4.next =&t5;
  t5.next =&t6;
  t6.next =&t7;
  head =&t1;//将t1地址给头
  struct test new2 ={101,NULL};//定义一个新节点,并传实参
  head=insertfromfor(head,1,&new2);//调用插头函数,并赋值把返回值给头
  puts("after insert head:\n");
  printlink(head);//输出打印
  system("pause");
  return 0;
}

链表前插法之插链表身

#include <stdio.h>
struct test
{
  int data;
  struct test *next;
};
struct test* insertfromfor(struct test *head,int data,struct test *new)//定义头插法
{
  struct test *p =head;//定义结构体指针p,并传参形参head
  if(p->data==data)//如果p的数据和形参中的数值相等
  {
    new->next=head;//将新的节点的下一个给头(头插法之插头)
    return new;//返回新节点
  }
  while(p->next !=NULL)//当指针p不为空时
  {
    if(p->next->data==data)//如果p的下一个的数据等于形参中的数据
    {
      new->next=p->next;//新节点的下一个给原p指针节点的下一个
      p->next=new;p节点的下一个给新节点
      printf("insert ok\n");//输出
      return head;
    }
    p=p->next;//如果没找到下一个,就执行下一个遍历到下一个,直到if语句成立
  }
  printf("no this data %d\n",data);//说明wille语句中没找到传参的值,输出
  return head;
}
void printlink(struct test *head)
{
  struct test *point;
  point=head;
  while(point !=NULL)
  {
    printf("%d ",point->data);
    point = point->next;
  }   
  putchar('\n');
}
int main()
{
  struct test *head = NULL;
  putchar('\n');
  struct test t1 ={1,NULL};
  struct test t2 ={2,NULL};
  struct test t3 ={3,NULL};
  struct test t4 ={4,NULL};
  struct test t5 ={5,NULL};
  struct test t6 ={6,NULL};
  struct test t7 ={7,NULL};
  t1.next =&t2;
  t2.next =&t3;
  t3.next =&t4;
  t4.next =&t5;
  t5.next =&t6;
  t6.next =&t7;
  head =&t1;
  struct test new3 ={103,NULL};
  head=insertfromfor(head,4,&new3);
  puts("在4前面插个新数:\n");//在4前面插入103
  printlink(head);//调用输出函数
  system("pause");
  return 0;
}

链表删除节点之删头

#include <stdio.h>
#include <stdlib.h>
struct test
{
  int data;
  struct test *next;
};
void printlink(struct test *head)
{
  struct test *point;
  point=head;
  while(point !=NULL)
  {
    printf("%d ",point->data);
    point = point->next;
  }   
  putchar('\n');
}
struct test* deletnode(struct test *head , int data)//定义结构体变量删除节点
{
  struct test *p =head;//将形参头给指针变量p
  if(p->data==data)//如果p的数据与形参中的数据相同
  {
    head =head->next;//头的下一个给头,也就是下一个成头了
      free(p);//将原先头的地址空间释放
    return head;//返回头
  }
}
int main()
{ 
  struct test *head = NULL;
//  struct test t1 ={1,NULL};
  struct test *p = (struct test*)malloc (sizeof(struct test));//开辟指针变量p 的空间并强转成结构体struct test *型
  struct test t2 ={2,NULL};
  struct test t3 ={3,NULL};
  struct test t4 ={4,NULL};
  struct test t5 ={5,NULL};
  struct test t6 ={6,NULL};
  struct test t7 ={7,NULL};
  p->data =1;//给头赋值1
//  t1.next =&t2;
  p->next =&t2;//将p的下一个与t2的地址链接
  t2.next =&t3;
  t3.next =&t4;
  t4.next =&t5;
  t5.next =&t6;
  t6.next =&t7;
//  head =&t1;
  head =p;  //指针p是头
  printlink(head);//删除前输出一遍
  head = deletnode(head ,1);//删除第一个后
  printlink(head);//输出
  system("pause");
  return 0;
}

链表删除节点之删身

#include <stdio.h>
#include <stdlib.h>
struct test
{
  int data;
  struct test *next;
};
void printlink(struct test *head)
{
  struct test *point;
  point=head;
  while(point !=NULL)
  {
    printf("%d ",point->data);
    point = point->next;
  }   
  putchar('\n');
}
struct test* deletnode(struct test *head , int data)
{
  struct test *p =head;
  if(p->data==data)
  {
    head =head->next;
    free(p);
    return head;
  }
  while(p->next !=NULL)//当指针P的下一个不为空时
  {
    if(p->next->data==data)//如果p 的下一的数据等于形参的数据
    {
      //struct test *tmp =p;//动态创建时需要用到
      p->next =p->next->next;//将p的下一个的下一个等于P的下一个,也就是把P的下一个删除了直接连接到后面那一个了
      //free(tmp);//释放内存空间
      return head;
    }
    p=p->next;
  }
  return head;  
}
int main()
{ 
  struct test *head = NULL;
//  struct test t1 ={1,NULL};
  struct test *p = (struct test*)malloc (sizeof(struct test));
  struct test t2 ={2,NULL};
  struct test t3 ={3,NULL};
  struct test t4 ={4,NULL};
  struct test t5 ={5,NULL};
  struct test t6 ={6,NULL};
  struct test t7 ={7,NULL};
  p->data =1;
//  t1.next =&t2;
  p->next =&t2;
  t2.next =&t3;
  t3.next =&t4;
  t4.next =&t5;
  t5.next =&t6;
  t6.next =&t7;
//  head =&t1;
  head =p;  
  printlink(head);
  head = deletnode(head ,3);//传参删除数据3这个节点
  printlink(head);
  return 0;
}

动态链表的头插法

#include <stdio.h>
#include <stdlib.h>
struct test
{
  int data;
  struct test *next;
};
void printlink(struct test *head)
{
  struct test *point;
  point=head;
  while(point !=NULL)
  {
    printf("%d ",point->data);
    point = point->next;
  }   
  putchar('\n');
}
struct test* insertfromhead(struct test *head) //动态头插法
{
  struct test *new;//定义一个新的节点
  while(1)
  {
    new =(struct test *)malloc(sizeof(struct test));//开辟结构体空间
    printf("input your new node data:\n");//输出
    scanf("%d",&(new->data));//输入,传给新节点指针变量的地址
    if(new->data ==0)//如果输入的是0
    {
      printf("0 quit\n");//输出0
      return head;//返回 退出
    }
    if(head==NULL)//如果为空
    {
      head=new;将新的给头,也就是,一开始什么也没有,也就是第一个
    }
    else
    {
      new->next=head;//将新的下一个与头连接
      head=new;//将新的给头,也就是进来后新的就成了头
    }
  }
  return head;//返回
}
int main()
{ 
  struct test *head = NULL;//定义头为空
  head = insertfromhead(head);//调用函数,并给头
  printlink(head);//输出
  return 0;
}

链表动态头插法C语言源码的优化

#include <stdio.h>
#include <stdlib.h>
struct test
{
  int data;
  struct test *next;
};
void printlink(struct test *head)
{
  struct test *point;
  point=head;
  while(point !=NULL)
  {
    printf("%d ",point->data);
    point = point->next;
  }   
  putchar('\n');
}
struct test* insertfromhead(struct test *head,struct test *new)//定义结构体指针变量头插法
{
    if(head==NULL)//如果头进来为空
    {
      head=new;//那么将新的节点给头
    }
    else//如果不是
    {
      new->next=head;//将新节点的下一个给头,也就是与之前的头连接
      head=new;//并将新节点给头,也就是新的成了头了
    }
    return head;
}
struct test* createlink(struct test *head)//定义结构体调用函数
{
  struct test *new;
  while(1)
  {
    new =(struct test *)malloc(sizeof(struct test));//开辟新的空间
    printf("input your new node data:\n");//输出打印新的节点的数据
    scanf("%d",&(new->data));//输入,传给新的数据
    if(new->data ==0)//如果输入的新的数据为0
    {
      printf("0 quit\n");//输出0
      free(new);//释放内存空间
      return head;返回头
    }
    head = insertfromhead(head,new);//调用头插法函数并将返回数据给头
  }
}
int main()
{ 
  struct test *head = NULL;//定义结构体指针头变量为空
  head = createlink(head);//调用函数
  printlink(head);//调用输出函数
  struct test t1 ={1000,NULL};//定义结构体t1,并传参
  head = insertfromhead(head,&t1);//调用头插法函数并传参给头
  printlink(head);//调用输出
  return 0;
}

链表动态尾插法C语言源码

#include <stdio.h>
#include <stdlib.h>
struct test
{
  int data;
  struct test *next;
};
void printlink(struct test *head)
{
  struct test *point;
  point=head;
  while(point !=NULL)
  {
    printf("%d ",point->data);
    point = point->next;
  }   
  putchar('\n');
}
struct test* insertbehind (struct test *head,struct test *new)
{
  struct test *p =head;
  if(p==NULL)
  {
    head=new;//将新的给头
    return head;
  }
  while(p->next != NULL)
  {
    p=p->next;//将原节点下一个给原节点
  }
  p->next =new;//将新的给原节点的下一个,也就是在原来的后面加上个新的
  return head;
}
struct test* createlink2(struct test *head)//动态后插法
{
  struct test *new;
  while(1)
  {
    new =(struct test *)malloc(sizeof(struct test));
    printf("input your new node data:\n");
    scanf("%d",&(new->data));
    if(new->data ==0)
    {
      printf("0 quit\n");
      free(new);
      return head;
    }
    head = insertbehind(head,new);
  }
}
int main()
{ 
  struct test *head = NULL;
  head = createlink2(head);
  printlink(head);
  struct test t2 ={2000,NULL};
  head =insertbehind(head,&t2); 
  printlink(head);
  return 0;
}
相关文章
|
8月前
|
Java
LinkedList与链表(有源码剖析)(一)
LinkedList与链表(有源码剖析)
72 0
|
2月前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
114 4
|
3月前
|
存储 Java
HashMap之链表转红黑树(树化 )-treefyBin方法源码解读(所有涉及到的方法均有详细解读,欢迎指正)
本文详细解析了Java HashMap中链表转红黑树的机制,包括树化条件(链表长度达8且数组长度≥64)及转换流程,确保高效处理大量数据。
113 1
|
2月前
|
C语言
【数据结构】双向带头循环链表(c语言)(附源码)
本文介绍了双向带头循环链表的概念和实现。双向带头循环链表具有三个关键点:双向、带头和循环。与单链表相比,它的头插、尾插、头删、尾删等操作的时间复杂度均为O(1),提高了运行效率。文章详细讲解了链表的结构定义、方法声明和实现,包括创建新节点、初始化、打印、判断是否为空、插入和删除节点等操作。最后提供了完整的代码示例。
78 0
|
5月前
【数据结构】双向带头(哨兵位)循环链表 —详细讲解(赋源码)
【数据结构】双向带头(哨兵位)循环链表 —详细讲解(赋源码)
97 4
|
5月前
|
存储 测试技术
【初阶数据结构篇】单链表的实现(附源码)
在尾插/尾删中,都需要依据链表是否为空/链表是否多于一个节点来分情况讨论,目的是避免对空指针进行解引用造成的错误。
45 0
|
8月前
|
缓存 算法 搜索推荐
【数据结构】链表(单链表与双链表实现+原理+源码)
【数据结构】链表(单链表与双链表实现+原理+源码)
|
8月前
|
算法 Java 索引
【数据结构与算法】4、双向链表(学习 jdk 的 LinkedList 部分源码)
【数据结构与算法】4、双向链表(学习 jdk 的 LinkedList 部分源码)
77 0
|
8月前
|
应用服务中间件 nginx
Nginx源码阅读:ngx_list_t 链表
Nginx源码阅读:ngx_list_t 链表
108 0
|
8月前
|
存储 Java 容器
LinkedList与链表(有源码剖析)(二)
LinkedList与链表(有源码剖析)(二)
49 0

热门文章

最新文章