关于链表的TIPS:

  • 链表中各结点在内存中可以不是连续存放的,各数据接点的存储顺序与数据元素之间的逻辑关系可以不一致,而数据元素之间的逻辑关系是由指针域来确定的。
  • 在链表结点 的数据结构中,结构体内的指针域的数据类型可以使用未定义成功的数据类型,这是C语言中唯一规定可以先使用后定义的数据结构
  • 头指针:存放一个地址(头结点地址),指向第一个结点(一定不要把头结点当做头指针,头指针只不过是储存头结点的地址而已,我在学的时候这里总出错
  • 具体链表的结构体建立,包括链表的指针域和数据域如下:

struct student
{
int num;
float score;
student *next;
};

  • 建立单链表的一些约定

    • 每个结点类型用LinkList表示

      • 数据域 data(类型:通用类型标识符 ElemType)
      • 指针域 next

typedef struct LNode
{
ElemType data;
struct LNode *next;
}LinkList;

  • 关于链表头结点的问题,有头结点只是为了方便计算(删除、插入……),因为只要掌握了表头,就可以访问整个链表

创建单链表

  • 头插法

    • 新产生的结点作为新的表头插入链表
(第一次执行②的作用是确定尾指针NULL)
#include<stdio.h>LinkList*CreateListF(ElemType a[],int n)
{LinkList*head,*s;int i;head = (LinkList*)malloc(sizeof(LinkList));    //创建头结点head->next = NULL;for(i=0;i<n;i++){s = (LinkList*)malloc(sizeof(LinkList));    //创建新结点s->data=a[i];s->next=head->next;    //第一次执行时是为了确定尾指针NULLhead->next=s;    //将*s插在原开始结点之前、头结点之后}return head;
}

  • 尾插法( 一句话,相当于不断开创新的结点,然后不断将新的结点的地址当做尾结点。尾结点不断后移,而新创的结点时按照创建的先后顺序而连接的。先来新到

    • 新的结点插入到当前链表的表尾,使其成为当前链表的尾结点
    • 尾插法创建第一个结点
      • 刚开始为头结点开辟内存空间,因为此时除头结点没有新的结点的建立,接着将头结点的指针域 head->next 的地址赋为 NULL。
      • 此时,整个链表只有一个头结点有效,因此这时head既是头结点,又是尾结点。将头结点的地址赋给尾结点end后:end = head。 (此时end 就是 head, head 就是 end。 end->next 也自然指向的是 NULL。)
    • 尾插法创建第二个结点
      • 创建完第一个结点之后,我们开始创建第二个结点。第一个结点,end 和 head 共用一块内存空间。现在从堆中心开辟出一块内存给 node,将 node 的数据域赋值后,此时 end 中存储的地址是 head 的地址。此时,end->next 代表的是头结点的指针域,因此 end->next = node 代表的就是将上一个,也就是新开辟的 node 的地址赋给 head 的下一个结点地址。
      • 此时,end->next 的地址是新创建的 node 的地址,而此时 end 的地址还是 head 的地址。 因此 end = node ,这条作用就是将新建的结点 node 的地址赋给尾结点 end。 此时 end 的地址不再是头结点,而是新建的结点 node。
    • 尾插法创建单链表,结点创建完毕
      • 最后,当结点创建完毕,最后不会有新的结点来替换 end ,因此最后需要加上一条 end->next = NULL。将尾指针的指向为 NULL
Linklist Creat_list(Linklist head) {head = (Linklist)malloc(sizeof(Lnode));          //  为头指针开辟内存空间Linklist node = NULL;           //  定义结点Linklist end = NULL;            //  定义尾结点head->next = NULL;              //  初始化头结点指向的下一个地址为 NULLend = head;                     //  未创建其余结点之前,只有一个头结点int count = 0 ;                 //  结点个数printf("Input node number: ");scanf("%d", &count);for (int i = 0; i < count; i++) {node = (Linklist)malloc(sizeof(Lnode));          //  为新结点开辟新内存node->data = i;                                  //  新结点的数据域赋值end->next = node;                              end = node;}end->next = NULL;
}//完整的代码实践
#include<stdio.h>
#include<stdlib.h>struct node
{int num,score;struct node*next;
};
int main()
{struct node*creat(int n);void print(struct node*);struct node*head=0;head=creat(5);print(head);return 0;}struct node*creat(int n){struct node*h=0,*p,*q;int i;h=(struct node*)malloc(sizeof(struct node));p=h;h->next=0;scanf("%d%d",&h->num,&h->score);    //初始化头指针for(i=1;i<n;i++){q=(struct node*)malloc(sizeof(struct node));scanf("%d%d",&q->num,&q->score);if(h==0)h=q;    //如果malloc函数申请空间失败,则q变成头结点elsep->next=q;p=q;}p->next=0;return h;}void print(struct node*h)    //输出不带头结点的链表{while(h){printf("num=%dtscore=%dn",h->num,h->score);h=h->next;}}

单链表的基本运算

  • 初始化链表InitList
LinkList*InitList()
{LinkList*head;head=(LinkList*)malloc(sizeof(LinkList));head->next=NULL;return head;
}

  • 销毁链表

    • 逐一释放全部结点空间
void DestroyList(LinkList*head)
{LinkList*p=head,*q;while(p!=NULL){q=p;p=p->next;free(q);}
}

  • 求链表长度
int ListLength(LinkList*head)
{LinkList*p=head;int i=0;while(p!=NULL){i++;p=p->next;}return(i);
}

  • 判定链表是不是空表
int ListEmpty(LinkList*head)
{return(head->next==NULL);
}

  • 输出链表
void DispList(LinkList*head)
{LinkList*p=head;while(p!=NULL){printf("%c",p->data);p=p->next;}printf("n");
}

  • 求指定位置的某个数据元素(在链表中从头开始找到第i个数据结点,若存在,则将其data域值通过变量e带回)
int GetELem(LinkList*head,int i,Elem Type*e)
{int j=1;LinkList*p=head->next;while(p!=NULL&&j<i){j++;p=p->next;}if(p==NULL)return 0;else{*e=p->data;return 1;    //表示代码执行成功}
}

  • 按元素值定位查找(在链表中从头开始找第一个值域与e相等的结点,若存在,则返回其次序,否则返回0)
int LocateElem(LinkList*head,Elem Type e)
{int n=1;LinkList*p=head->next;while(p!=NULL&&p->data!=e){n++;p=p->next;}if(p=NULL)return 0;elsereturn n;
}

  • 插入数据元素(先在链表中找到第i个结点*p,若存在,将值为e分结点*s插入其后)
int ListInsert(LinkList*head,int i,ElemType e)
{int j=0;LinkList*p=head,*s;while(p!=NULL&&j<i-1){j++;p=p->next;}if(p==NULL)return 0;else{s=(LinkList*)malloc(sizeof(LinkList));s->data=e;s->next=p->next;p->next=s;return 1;}
}

  • 删除数据元素
int ListDelete(LinkList*head,int i,ElemType e)
{int j=0;LinkList*p=head,*q;while(p!=NULL&&j<i-1){j++;p=p->next;}if(p==NULL)return 0;else{q=p->next;if(q==NULL)return 0;p->next=q->next;free(q);return 1;}
}

  • 链表的逆置
算法图解
void RevLink(LinkList L)
{Node *p=L->next,*q;  //创建指针p使其指向第二个结点(L是第一个结点的地址,L->next是第二个结点的地址)L->next=NULL;        //这里是说把第一个结点的指针域置0,这样就为第一个结点作尾结点做准备(因为逆置后原来的第一个结点就变成了尾结点呀)while(q){q=p->next;        //只要第一个结点之后一直有结点,q指针就一直向下走,直到q为空p->next=L->next;    //插入操作,将逆置的结点往头结点之前插L->next=p;     //将链表连接起来p=q;}
}

  • 单链表的连接(数据域排序)
LinkList MergeLinkList(LinkList LA,LinkList LB)
{Node *pa,*pb;LinkList LC;pa=LA->next;pb=LB->next;LC=LA;           //建立两个链表连接之后的新链表的头指针 LC->next=NULL;r=LC;           //r是一个搜索指针,从头开始,最后成为尾指针 while(pa&&pb){if(pa->data<=pb->data){r->next=pa;r=pa;pa=pa->next;}else{r->next=pb;r=pb;pb=pb->next;}}if(pa)               //根据pa是否为空,判断最后的尾指针是谁 r->next=pa;elser->next=pb;free(LB);            //释放多余的空间 return(LC);} 

本人也是第一次写知乎文章,希望对童鞋们有帮助呀,我也是一个大学生,还在学习中,这是我每天学习自己进行的总结和知识理解梳理,如果有错误的话希望大佬多多指教,后续我会继续更新C语言的知识梳理类文章,如果觉得文章对你有帮助的话,别忘了点下赞或者评下论再走哦!

c语言 链表_小陈的C语言笔记---链表(详细讲解基本操作和概念)相关推荐

  1. 用python语言写小程序_小程序用什么语言开发?python语言开发可以开发吗?

    时间: 2020-01-04 20:16:44 本次介绍小程序用什么语言开发?python语言开发可以开发吗?小程序开发语言前端三件套:1.WXML文件2.WXSS文件3.JS文件 小程序是什么?通俗 ...

  2. c语言射击类小游戏任务书,(c语言课程设计报告小游戏“石头剪子布”.doc

    (c语言课程设计报告小游戏"石头剪子布" <C语言课程设计>报告 题目:石头剪子布 班级: 学号: 姓名: 指导教师: 成绩: 目 录: 一.选题背景- 3 - 二.设 ...

  3. php语言学习_新手如何学习PHP语言

    新手如何学习PHP语言 php语言是一种通用开源脚本语言,那么作为新手,你知道该如何学习php语言吗,下面我们一起来看看吧. 新手如何学习PHP语言 1.Php的用途是什么? 对于一个php门外汉来说 ...

  4. c语言程序设计猜拳小游戏答辩,C语言课程设计猜拳游戏.doc

    C语言程序设计 课程设计(论文) 题目: 院(系): 专业班级: 学 号: 学生姓名: 指导教师: 教师职称: 起止时间: 课程设计(报告)任务及评语 院(系):软件学院 教研室:软件教研窒 学 号学 ...

  5. vins中imu融合_小觅智能 | VINS 学习笔记(持续更新中)

    VINS 基本介绍 VINS-Mono 和 VINS-Mobile 是香港科技大学沈劭劼老师开源的单目视觉惯导 SLAM 方案.2017年发表于<IEEE Transactions on Rob ...

  6. 广东蓝桥杯c语言编译器_小软访谈之榜样充电站 千里之行,始于足下——“蓝桥杯”获奖者采访...

    小软访谈之榜样充电站 千里之行,始于足下--"蓝桥杯"获奖者采访 大学生活是丰富的.是自由的,但要如何去规划.管理时间,是每名大学生所需要思考的重要问题.小软今天采访到的就是两位充 ...

  7. c语言2048项目报告,c语言----项目_小游戏2048

    2048 小游戏 主要是针对逻辑思维的一个训练. 主要学习方面:1.随机数产生的概率.2.行与列在进行移动的时候几种情况.3.messagebox的使用 #include #include #incl ...

  8. 计算机java语言答案_【计算机二级Java语言】卷019

    选择题 公共知识 [1]下列叙述中正确的是 [A]算法的时间复杂度与计算机的运行速度有关 [B]算法的时间复杂度与运行算法时特定的输入有关 [C]算法的时间复杂度与算法程序中的语句条数成正比 [D]算 ...

  9. 小陈的java学习笔记

    两周的总结 Java的环境搭建 环境变量的配置 新建 系统变量: JAVA_HOME 变量值: 文本框输入JDK的安装路径 在系统变量PATH,的文本框的起始位置添加 %JAVA_HOME%\bin; ...

最新文章

  1. docker nginx部署前端项目
  2. mysql表连接算法_如何在MySQL中连接多个表
  3. [Swift通天遁地]七、数据与安全-(19)使用Swift实现原生的SHA1加密
  4. sizeof()浅解
  5. 十二、深入Python列表和元组
  6. CMS之promotion failedconcurrent mode failure
  7. mysql 存储过程 replace_mysql replace存储过程
  8. glibc free 死锁
  9. 吴恩达深度学习神经网络基础编程作业Building your Deep Neural Network Step by Step
  10. 修改java或css后不生效,还是显示修改之前的样式,问题已解决
  11. Conflux吐槽君:IOTA物联网电磁炉-让PoW的耗电没有遗憾
  12. IntelliJ IDEA 无法导入HttpServlet包解决方法
  13. oracle安装5.1,5.1 Oracle RAC的安装(5)
  14. 【收藏】DIABLO 2 CD KEY
  15. android 手机屏蔽广告 hosts
  16. 笔记本电脑蓝牙怎么用来连接耳机
  17. Android自定义消息推送
  18. 中文.com域名如何申请 什么是.com域名过期
  19. 微信开放平台 公众号第三方平台开发 教程二 创建公众号第三方平台
  20. 驱动精灵 v9.61 去广告最终版绿色清爽单文件

热门文章

  1. 2016.3 idea 注册码
  2. 最短路问题(Bellman/Dijkstra/Floyd)
  3. Objective-C日记-之KVC
  4. matplotlib快速画图
  5. 简述mysql事件作用_MYSQL使用简述
  6. wireshark不显示rtsp问题(四)
  7. Linux音频驱动开发概括
  8. 多速率多传感器数据融合估计(一)
  9. prolog参考手册学习(第一章)
  10. tensorflow之ExponentialMovingAverage