1,为什么要用到链表

数组作为存放同类数据的集合,给我们在程序设计时带来很多的方便,增加了灵活性。但数组也同样存在一些弊病。如数组的大小在定义时要事先规定,不能在程序中进行调整,这样一来,在程序设计中针对不同问题有时需要3 0个大小的数组,有时需要5 0个数组的大小,难于统一。我们只能够根据可能的最大需求来定义数组,常常会造成一定存储空间的浪费。

我们希望构造动态的数组,随时可以调整数组的大小,以满足不同问题的需要。链表就是我们需要的动态数组。它是在程序的执行过程中根据需要有数据存储就向系统要求申请存储空间,决不构成对存储区的浪费。

链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表、循环链表、双向链表,下面将逐一介绍。

2,单向链表

单链表有一个头节点head,指向链表在内存的首地址。链表中的每一个节点的数据类型为结构体类型,节点有两个成员:整型成员(实际需要保存的数据)和指向下一个结构体类型节点的指针(它是节点类型)即下一个节点的地址(事实上,此单链表是用于存放整型数据的动态数组)。链表按此结构对各节点的访问需从链表的头找起,后续节点的地址由当前节点给出。无论在表中访问那一个节点,都需要从链表的头开始,顺序向后查找。链表的尾节点由于无后续节点,其指针域为空,写作为NULL

如图所示

上图还给出这样一层含义,链表中的各节点在内存的存储地址不是连续的,其各节点的地址是在需要时向系统申请分配的,系统根据内存的当前情况,既可以连续分配地址,也可以跳跃式分配地址。

3,单向链表程序的实现

(1),链表节点的数据结构定义

struct node
{
int num;
struct node *p;
} ;

在链表节点的定义中,除一个整型的成员外,成员p是指向与节点类型完全相同的指针。

在链表节点的数据结构中,非常特殊的一点就是结构体内的指针域的数据类型使用了未定义成功的数据类型。这是在C中唯一规定可以先使用后定义的数据结构。

(2),链表的创建、输出步骤

单链表的创建过程有以下几步:

1 ) 定义链表的数据结构(即定义节点的数据结构);

2 ) 创建一个空表;

3 ) 利用malloc ( )函数向系统申请分配一个节点;

4 ) 将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新

节点接到表尾;

5 ) 判断一下是否有后续节点要接入链表,若有转到3 ),否则结束;

单链表的输出过程有以下几步

1) 找到表头;

2) 若是非空表,输出节点的值成员,是空表则退出;

3 ) 跟踪链表的增长,即找到下一个节点的地址;

4) 转到2 ).

(3),程序代码例子:

创建一个存放正整数单链表,输入0或小于0的数,结束创建链表,并打印出链表中的值,程序如下:

#include <stdlib.h> /*含ma l l o c ( ) 的头文件*/
#include <stdio.h>
struct node //①定义链表数据结构
{
int num;
struct node *next;
};
main( )
{
struct node *creat();
void print();
struct node *head;
head=NULL; //②建一个空表
head=creat(head);/*创建单链表*/
print(head);/*打印单链表*/
}
/******************************************/
struct node*creat(struct node *head)/*返回的是与节点相同类型的指针*/
{
struct node*p1,*p2;
//③利用malloc ( )函数向系统申请分配一个节点
p1=p2=(struct node*)malloc(sizeof(struct node));/*新节点*/
printf("p1= %d\n",p1);
scanf("%d",&p1->num);/*输入节点的值*/
p1->next=NULL;/*将新节点的指针置为空*/
while(p1->num>0)/*输入节点的数值大于0*/
{
//④将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新
//节点接到表尾;
if(head==NULL)
head=p1;/*空表,接入表头*/
else
p2->next=p1;/*非空表,接到表尾*/
p2=p1;
p1=(struct node*)malloc(sizeof(struct node));/*下一个新节点*/
printf("p2= %d\n",p2);
scanf("%d",&p1->num);/*输入节点的值*/
//⑤判断一下是否有后续节点要接入链表,若有转到3 ),否则结束;
}
printf("p2->next=%d\n",p2->next);
return head;/*返回链表的头指针*/
}
/*******************************************/
void print(struct node*head)/*出以head为头的链表各节点的值*/
{
struct node *temp;
temp=head;/*取得链表的头指针*/
while(temp!=NULL)/*只要是非空表*/
{
printf("%6d",temp->num);/*输出链表节点的值*/
temp=temp->next;/*跟踪链表增长*/
}
}

编译后执行:

p1= 140660744  //链表头

1

p2= 140660760

45

p2= 140660776

6

p2= 140660792

77

p2= 140660808

88

p2= 140660824

0                               //输入0结束增加链表

p2->next=0       //链表结尾

1       45    6    77    88          //输出链表的值。

在链表的创建过程中,链表的头指针是非常重要的参数。因为对链表的输出和查找都要从链表的头开始,所以链表创建成功后,要返回一个链表头节点的地址,即头指针

程序执行流程:

C语言单向链表的更多相关文章

  1. c语言单向链表逆转实现方法

    自己理解的思路如下所示: 从第二个节点开始,先记录下一个节点,把第二个节点移到头节点之前,头节点变为移动的这个节点之前记录的节点变为接下来要移动的节点用for循环重复最后把原来头节点变成尾节点(*ne ...

  2. C语言通讯录系统——C语言单向链表实现

    实现的通讯录功能有:查看通讯录.添加联系人.删除联系人.查询联系人.保存并退出. 通过txt文件保存和读取通讯录数据. #include <stdio.h> #include <st ...

  3. ZT C语言链表操作(新增单向链表的逆序建立)

    这个不好懂,不如看 转贴:C语言链表基本操作http://www.cnblogs.com/jeanschen/p/3542668.html ZT 链表逆序http://www.cnblogs.com/ ...

  4. C语言实现单向链表及其各种排序(含快排,选择,插入,冒泡)

    #include<stdio.h> #include<malloc.h> #define LEN sizeof(struct Student) struct Student / ...

  5. C语言基础 - 实现单向链表

    回归C基础 实现一个单向链表,并有逆序功能 (大学数据结构经常是这么入门的) //定义单链表结构体 typedef struct Node{ int value; struct Node *next; ...

  6. C语言:创建动态单向链表,创建完成后,输出每一个节点的数据信息。

    // //  main.c //  dynamic_link_list // //  Created by ma c on 15/8/5. //  Copyright (c) 2015. All ri ...

  7. C语言实现简单的单向链表(创建、插入、删除)及等效STL实现代码

    实现个算法,懒得手写链表,于是用C++的forward_list,没有next()方法感觉很不好使,比如一个对单向链表的最简单功能要求: input: 1 2 5 3 4 output: 1-> ...

  8. C语言:将ss所指字符串中所有下标为奇数位上的字母转换成大写,若不是字母,则不转换。-删除指针p所指字符串中的所有空白字符(包括制表符,回车符,换行符)-在带头结点的单向链表中,查找数据域中值为ch的结点,找到后通过函数值返回该结点在链表中所处的顺序号,

    //将ss所指字符串中所有下标为奇数位上的字母转换成大写,若不是字母,则不转换. #include <stdio.h> #include <string.h> void fun ...

  9. C语言:将带头节点的单向链表结点域中的数据从小到大排序。-求出单向链表结点(不包括头节点)数据域中的最大值。-将M*N的二维数组中的数据,按行依次放入一维数组,

    //函数fun功能是将带头节点的单向链表结点域中的数据从小到大排序. //相当于数组的冒泡排序. #include <stdio.h> #include <stdlib.h> ...

随机推荐

  1. Git安装和使用(谨记)

    刚开始用git的小白适用,,转自http://www.cnblogs.com/qijunjun/p/7137207.html 实际项目开发中,我们经常会用一些版本控制器来托管自己的代码,今天就来总结下 ...

  2. Vuejs环境安装与工程建立【小白Windows向】

    不知道为什么CDN的方式就是困难...大佬说SPA必须配置本地开发环境,那就配咯. 所以就准备了以下的工具进行安装本地开发环境: 1. 代码编辑器×1[本人使用VSCode 1.11] 2. Node ...

  3. cat/tac/more/less 命令详解

    cat:(http://www.cnblogs.com/peida/archive/2012/10/30/2746968.html) *cat主要有三大功能:1.一次显示整个文件:cat filena ...

  4. Elasticsearch索引自动删除

    简介 脚本分2部分,1部分查找符合条件的索引名,2脚本调用1脚本,进行删除操作 脚本 查找符合条件的,默认大于30天 # coding:utf-8 __author__ = 'Jipu FANG' f ...

  5. NIO中的易筋经

    匠心零度 转载请注明原创出处,谢谢! 前言 <易筋经>.天下武功出少林,而易筋经是少林寺的镇寺之宝.学好了易筋经就可以轻易地学好其它武功,只不过很少人学到了它的全部精髓.游坦之只是碰巧学了 ...

  6. Django2中文文档--目录及介绍部分

    Django2文档-文档结构 我是按照官方文档的格式进行翻译,所以格式根官方格式一致 如果大家发现哪些地方有问题可以联系我 2426525089@qq.com 或者加入QQ群跟我一起翻译,群号码: 2 ...

  7. JQuery和JS操作LocalStorage/SessionStorage的方法

    LocalStorage 是对Cookie的优化 没有时间限制的数据存储 在隐私模式下不可读取 大小限制在500万字符左右,各个浏览器不一致 在所有同源窗口中都是共享的 本质是在读写文件,数据多的话会 ...

  8. ASP.NET如何通过后台数据库提供的链接播放视频(不使用外置插件)

    1.后台视频数据库: 2.aspx中的关键代码: <asp:DataList ID="DataList2" runat="server" DataKeyF ...

  9. swiper轮播问题之一:轮播图内容为动态数据生成时轮播图无法自动轮播

    本人在用H5做移动端项目中使用Swiper遇到的两个问题,因此加深了对Swiper的掌握,分享出来对刚开始接触Swiper的童鞋们或多或少会有帮助.        首先,new Swiper的初始化最 ...

  10. Mongo查询关键字