Linux C语言链表详细分析

链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。说到这里你应该就明白了,链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。

  作为有强大功能的链表,对他的操作当然有许多,比如:链表的创建,修改,删除,插入,输出,排序,反序,清空链表的元素,求链表的长度等等。

  初学链表,一般从单向链表开始

  --->NULL

  head

  这是一个空链表。

  ---->[p1]---->[p2]...---->[pn]---->[NULL]

  head p1->next p2->next pn->next

  有n个节点的链表。

  创建链表

  typedef struct student{

  int score;

  struct student *next;

  } LinkList;

  一般创建链表我们都用typedef struct,因为这样定义结构体变量时,我们就可以直接可以用LinkList *a;定义结构体类型变量了。

  初始化一个链表,n为链表节点个数。

LinkList *creat(int n){

  LinkList *head, *node, *end;//定义头节点,普通节点,尾部节点;

  head = (LinkList*)malloc(sizeof(LinkList));//分配地址

  end = head; //若是空链表则头尾节点一样

  for (int i = 0; i < n; i++) {

  node = (LinkList*)malloc(sizeof(LinkList));

  scanf("%d", &node->score);

  end->next = node;

  end = node;

  }

  end->next = NULL;//结束创建

  return head;

  }

  修改链表节点值

  修改链表节点值很简单。下面是一个传入链表和要修改的节点,来修改值的函数。

void change(LinkList *list,int n) {//n为第n个节点

  LinkList *t = list;

  int i = 0;

  while (i < n && t != NULL) {

  t = t->next;

  i++;

  }

  if (t != NULL) {

  puts("输入要修改的值");

  scanf("%d", &t->score);

  }

  else {

  puts("节点不存在");

  }

  }

  删除链表节点

  删除链表的元素也就是把前节点的指针域越过要删除的节点指向下下个节点。即:p->next = q->next;然后放出q节点的空间,即free(q);

void delet(LinkList *list, int n) {

  LinkList *t = list, *in;

  int i = 0;

  while (i < n && t != NULL) {

  in = t;

  t = t->next;

  i++;

  }

  if (t != NULL) {

  in->next = t->next;

  free(t);

  }

  else {

  puts("节点不存在");

  }

  }

  插入链表节点

  我们可以看出来,插入节点就是用插入前节点的指针域链接上插入节点的数据域,再把插入节点的指针域链接上插入后节点的数据域。根据图,插入节点也就是:e->next = head->next; head->next = e;

  增加链表节点用到了两个结构体指针和一个int数据。

 void insert(LinkList *list, int n) {

  LinkList *t = list, *in;

  int i = 0;

  while (i < n && t != NULL) {

  t = t->next;

  i++;

  }

  if (t != NULL) {

  in = (LinkList*)malloc(sizeof(LinkList));

  puts("输入要插入的值");

  scanf("%d", &in->score);

  in->next = t->next;//填充in节点的指针域,也就是说把in的指针域指向t的下一个节点

  t->next = in;//填充t节点的指针域,把t的指针域重新指向in

  }

  else {

  puts("节点不存在");

  }

  }

  输出链表

  输出链表很简单,边遍历边输出就行了。

 while (h->next != NULL) {

  h = h->next;

  printf("%d ", h->score);

  }

分享些链表资料便于更好的参考学习

C语言玩转链表 http://www.makeru.com.cn/live/1392_338.html?s=45051

C语言编程基础 http://www.makeru.com.cn/course/details/2233?s=45051

循环链表及线性表的应用 http://www.makeru.com.cn/course/details/1902?s=45051

原文链接:https://www.cnblogs.com/923327iu/p/11946825.html

编辑于

相关文章

来自专栏Opensource翻译专栏

C的巨大影响【Programming】

Command Line Heroes本季最后一期告诉我们一小群开源爱好者是如何改变世界的。

10100
来自专栏诸葛青云的专栏

C语言这么厉害,它自身又是用什么语言写的?

换个角度来问,其实是:C语言在运行之前,得编译才行,那C语言的编译器从哪里来? 用什么语言来写的?如果是用C语言本身来写的,到底是先有蛋还是先有鸡?

9720
来自专栏诸葛青云的专栏

学习凭自学C语言能到达什么高度

拿我一个朋友的故事来讲,小滔作为非科班学金融的大学生,在大二的时候迷上了IT这个行业,于是准备转专业IT,说干就干,每次下课有时间小滔便去蹭课,没有蹭课的空闲时...

11120
来自专栏前端桃园

async/await 原理及执行顺序分析

之前写了篇文章《这一次,彻底理解Promise原理》,剖析了Promise的相关原理。我们都知道,Promise解决了回调地狱的问题,但是如果遇到复杂的业务,代...

12120
来自专栏诸葛青云的专栏

c++和c语言之间有什么区别

  C语言是一种古老而又经久不衰的计算机程序设计语言,大约诞生于上个世纪60年代。由于它的设计有很多优点,多年以来深受广大程序设计人员的喜爱,并逐渐 淘汰了很多...

16330
来自专栏C语言及其他语言

time库函数总结

参数说明: timer=NULL时得到当前日历时间(从1970-01-01 00:00:00到现在的秒数),timer=时间数值时,用于设置日历时间,time_...

7320
来自专栏Web技术布道师

php://output和php://stdout的区别

PHP包含了以php://开头的一系列输出输出流,如php://stdin, php://stdout等。今天查看代码时,忽然想到一个问题:php://outp...

8010
来自专栏C语言入门到精通

基础知识 | 每日一练(175)

士人有百折不回之真心,才有万变不穷之妙用。立业建功,事事要从实地着脚,若少慕声闻,便成伪果;讲道修德,念念要从虚处立基,若稍计功效,便落尘情。 ...

5510
来自专栏C语言入门到精通

基础知识 | 每日一练(174)

士人有百折不回之真心,才有万变不穷之妙用。立业建功,事事要从实地着脚,若少慕声闻,便成伪果;讲道修德,念念要从虚处立基,若稍计功效,便落尘情。 ...

5910
来自专栏cwl_Java

Java基础-Java的特点

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

6320

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励