链表是一群结构体(称为结点)通过指针连起来。这种结构体类型,比较特殊,叫自引用结构体类型。它有一个指针指向和和结构体一样的类型,其余是数据成员。

头指针指向第一结点,尾指针一定要用空表示,这叫有头有尾。一般在表头加头结点,之后才是正式含数据的结点。

这些结点通过头指针访问,所以若头指针值为空,那么链表就为空。所以头指针是最重要的,一般一定会给函数传递头指针。

//-------------------------------------
//--- linked list.1
//--- 使用链表管理学生信息
//-------------------------------------
#include <stdio.h>
#include <stdlib.h> struct student
{
long no;
char name[20];
char addr[30];
struct student *next;
}; typedef struct student LIST;
LIST *CreateList();
void DispList(LIST *h);
void input(LIST *p);
LIST *DeleteNode(LIST *h, long no);
LIST *InsertNode(LIST *h, LIST *s); int main(int argc, char const *argv[])
{
LIST *head,*p;
long no;
int choice,confirm;
head=CreateList(); //创建链表,返回头指针
DispList(head); //输出链表内信息
while(1)
{
printf("0--Insert\n1--Delete\n2--Quit\nPlease select:");
scanf("%d",&choice);
if(choice==2)
break;
printf("your just select %d,yes? ",choice);
scanf("%d",&confirm);
if(confirm){
switch(choice)
{
case 0:
printf("OK,now we insert a record!\n");
printf("======Insert=====\n");
p=(LIST *)malloc(sizeof(LIST));
if(p == NULL)
{
printf("Wrong!\n");
exit(0);
}
input(p);
head=InsertNode(head,p);
DispList(head);
break;
case 1:
printf("OK,now we delete a record!\n");
printf("======Delete=====\n");
printf("Delete Id:");
scanf("%d",&no);
head=DeleteNode(head,no);
if (head!=NULL)
DispList(head);
else printf("All records have been deleted!\n");
break;
}
}
}
return 0;
}
void input(LIST *p)
{
LIST *cur=p;
printf("Id:");
scanf("%d", &cur->no);
printf("Name:");
scanf("%s", &cur->name);
printf("Address:");
scanf("%s", &cur->addr);
}
LIST *CreateList()/*返回头指针,故定义为结构体指针函数。*/
/*创建链表的函数定义*/
{
LIST *h, *prev, *cur;//这三不是结构体,是工作指针,用来操作的。
int i, n;
h=NULL;
/*第一个结点过来孤零零的,不知道干啥,所以得弄个头指针。初始化为空。*/
printf("Input numbers of records:");
scanf("%d",&n); for (int i = 0; i < n; i++)//for循环创建链表
{
cur=(LIST *)malloc(sizeof(LIST));/*LIST型指针,动态生成一个结点空间,返回首地址*/
if(cur == NULL)
{
printf("Wrong!\n");
exit(0);
}
cur->next=NULL;/*将cur的next置为NULL*/
if (h==NULL)/*如果h=NULL,表示当前在处理第一个结点*/
{
h=cur;/*令h指向第一个结点*/
}
else
prev->next=cur;
/*令表中最后一个结点的next指向cur;prev负责将链段尾结点和新结点连起来*/
/*关于指针指来指去,想想就好了,实际上指针都是地址,内存条里是不会有箭头的。要懂链表,先理解结构体。结构体变量可以通过变量名.成员名的方式访问成员,也可以用存储了结构体首地址的指针变量->成员名的形式访问成员。这里cur存储了新来的结构体的首地址,prev存储了链段尾结构体的首地址,你不妨将指针直接看成结构体,没什么不妥。那么让尾结构体的指针成员next存储新来的结构体的首地址,这样,通过链段尾结构体就可以访问新来的结构体的了,事实上只能这样访问,别无它法。正因为如此,一个结构体带一个结构体,才起名为链表。
通过prev->next就可以操作指针成员next。prev->next=cur执行后,prev就存储了新来结构体的首地址。由于新来的结构体已经安顿好了,它其实已经作为老结构体了,那么prev就存储了这个老结构体的首地址,你可以把prev看成这个老结构体。
*/
//input information
printf("=====第%d人=====\n",i+1);
input(cur); prev=cur;/*将prev指向最后一个结点;prev永远指向链段的最后一个结点*/
}
return h;
} void DispList(LIST *h)
{
LIST *p=h;
int i=0;
while(p!=NULL)
{
if(i==0)
{
printf("学号\t姓名\t地址\n");//只显示一次
i=1;
}
printf("%d\t%s\t%s\n",p->no, p->name, p->addr);
p=p->next;
}
} LIST *InsertNode(LIST *h, LIST *s)
{
LIST *pre, *p;
p=h;
if (h==NULL)
{
h=s;
s->next=NULL;
}else{
while((s->no > p->no) && (p->next!=NULL))
{
pre=p;
p=p->next;
}
if(s->no <= p->no){
if (h==p){
s->next=h;
h=s;
}else{
pre->next=s;
s->next=p;
}
}else{
p->next=s;
s->next=NULL;
}
}
return h;
} LIST *DeleteNode(LIST *h, long no)
{
LIST *pre, *p;
if (h==NULL)
{
printf("链表为空,不能删除结点!\n");
return NULL;
}
p=h;
while((p->no != no) && p->next!=NULL)
{
pre=p;
p=p->next;
}
if (p->no==no)
{
if (p==h)
h=p->next;
else pre->next=p->next;
free(p);
printf("结点成功删除\n");
}else printf("There isn't Id:%d.\n",no);
return h;
}

C语言语法教程-链表的更多相关文章

  1. C语言语法教程-结构体

    2018-09-30 结构体中成员变量地址是连续的,结构体用于描述记录. Create a struct //---------------------------- //struct1.c //创建 ...

  2. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  3. 《JavaScript语言入门教程》记录整理:运算符、语法和标准库

    目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...

  4. 学习Nim语言.rar(nim语言中文教程下载)

    学习Nim语言 nim 语法上类似python ,是一门静态编译型语言,nim 使用空格缩进标示语句块的开始和结束, 喜欢python风格的程序员应该也会很容易适应和喜欢nim的风格. nim语言官方 ...

  5. 「C语言」单链表/双向链表的建立/遍历/插入/删除

    最近临近期末的C语言课程设计比平时练习作业一下难了不止一个档次,第一次接触到了C语言的框架开发,了解了View(界面层).Service(业务逻辑层).Persistence(持久化层)的分离和耦合, ...

  6. 《Ruby语言入门教程v1.0》学习笔记-01

    <Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...

  7. C语言入门教程-(5)格式化输入输出

    1.输入和输出 在程序的使用中,我们经常可以看的这么一个场景:用户需要输入数据,经过程序运算,得到结果后输出.在C语言中,输入数据和输出数据都是由库函数完成的,通过语句来输入/输出. 2.格式化输出— ...

  8. 嵌入式C语言自我修养 01:Linux 内核中的GNU C语言语法扩展

    1.1 Linux 内核驱动中的奇怪语法 大家在看一些 GNU 开源软件,或者阅读 Linux 内核.驱动源码时会发现,在 Linux 内核源码中,有大量的 C 程序看起来“怪怪的”.说它是C语言吧, ...

  9. Go语言语法说明

    Go语言语法说明 go语言中的go func(){}() 表示以并发的方式调用匿名函数func 深入讲解Go语言中函数new与make的使用和区别 前言 本文主要给大家介绍了Go语言中函数new与ma ...

随机推荐

  1. Highways POJ - 1751

    题目链接:https://vjudge.net/problem/POJ-1751 思路: 最小生成树板子,只需要多记录每个dis[x]的权值是从哪个点到x这个点的. #include <stdi ...

  2. 关于使用repo时repo init和repo sync失败的一个解决方案

    由于我国的网络的原因,在访问谷歌等一些国外网络资源时经常会遇到被拦截的情况,导致repo等一些代码管理工具拉取代码网络受限受阻,下面提供一个可以参考的简单解决方案. 1.repo init时的遇到fa ...

  3. 跟着ALEX 学python day2 基础2 模块 数据类型 运算符 列表 元组 字典 字符串的常用操作

    声明 : 文档内容学习于 http://www.cnblogs.com/xiaozhiqi/  模块初始: Python的强大之处在于他有非常丰富和强大的标准库和第三方库,几乎你想实现的任何功能都有相 ...

  4. HTML与CSS学习笔记(1)

    1.web三大核心技术? HTML CSS JavaScript 2.HTML基本机构和属性 HTML:超文本 标记 语言 超文本:文本内容+非文本内容(图片.视频.音频等) 标记:<单词> ...

  5. 题解:[ZJOI2014]璀灿光华

    原题链接 OJ 题号 洛谷 3342 loj 2203 bzoj 3619 题目描述 金先生有一个女朋友没名字.她勤劳勇敢.智慧善良.金先生很喜欢她.为此,金先生用\(a^3\)块\(1 \times ...

  6. Visual Studio 2017 软件包及教程

    下载地址:https://files.cnblogs.com/files/yungle/VisualStudio2017.rar 安装教程:https://mp.weixin.qq.com/s?__b ...

  7. 测试脚本中的等待方法 alter对话框处理

    测试脚本中的等待方法 等待是为了使脚本执行更加稳定 1. 常用的休眠方式:time模块的sleep方法 2. selenium模块中的等待方法 等待查找5s 查找不到就报错 对登录测试py进行修改 a ...

  8. JAVA List中剔除空元素(null)的方法

    方法一.list.removeAll(Collections.singleton(null)); 方法二.List nullList = new ArrayList();                ...

  9. C# 集合根据属性去重筛选

    1.单个属性去重筛选 //去重筛选 var ChgDtlVoList = datas.Where((x, i) => datas.FindIndex(z => z.ChgId == x.C ...

  10. b站滑动验证码图片的获取-python

    本文仅是获取验证码图片,python+selenium实现 图片的处理,算出偏移位置网上都有现成的:而由于b站的更新,图片的获取则与之前完全不同,不能直接从html中拿到 过程比较曲折所以记录一下,可 ...