C语言单向链表
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语言单向链表的更多相关文章
- c语言单向链表逆转实现方法
自己理解的思路如下所示: 从第二个节点开始,先记录下一个节点,把第二个节点移到头节点之前,头节点变为移动的这个节点之前记录的节点变为接下来要移动的节点用for循环重复最后把原来头节点变成尾节点(*ne ...
- C语言通讯录系统——C语言单向链表实现
实现的通讯录功能有:查看通讯录.添加联系人.删除联系人.查询联系人.保存并退出. 通过txt文件保存和读取通讯录数据. #include <stdio.h> #include <st ...
- ZT C语言链表操作(新增单向链表的逆序建立)
这个不好懂,不如看 转贴:C语言链表基本操作http://www.cnblogs.com/jeanschen/p/3542668.html ZT 链表逆序http://www.cnblogs.com/ ...
- C语言实现单向链表及其各种排序(含快排,选择,插入,冒泡)
#include<stdio.h> #include<malloc.h> #define LEN sizeof(struct Student) struct Student / ...
- C语言基础 - 实现单向链表
回归C基础 实现一个单向链表,并有逆序功能 (大学数据结构经常是这么入门的) //定义单链表结构体 typedef struct Node{ int value; struct Node *next; ...
- C语言:创建动态单向链表,创建完成后,输出每一个节点的数据信息。
// // main.c // dynamic_link_list // // Created by ma c on 15/8/5. // Copyright (c) 2015. All ri ...
- C语言实现简单的单向链表(创建、插入、删除)及等效STL实现代码
实现个算法,懒得手写链表,于是用C++的forward_list,没有next()方法感觉很不好使,比如一个对单向链表的最简单功能要求: input: 1 2 5 3 4 output: 1-> ...
- C语言:将ss所指字符串中所有下标为奇数位上的字母转换成大写,若不是字母,则不转换。-删除指针p所指字符串中的所有空白字符(包括制表符,回车符,换行符)-在带头结点的单向链表中,查找数据域中值为ch的结点,找到后通过函数值返回该结点在链表中所处的顺序号,
//将ss所指字符串中所有下标为奇数位上的字母转换成大写,若不是字母,则不转换. #include <stdio.h> #include <string.h> void fun ...
- C语言:将带头节点的单向链表结点域中的数据从小到大排序。-求出单向链表结点(不包括头节点)数据域中的最大值。-将M*N的二维数组中的数据,按行依次放入一维数组,
//函数fun功能是将带头节点的单向链表结点域中的数据从小到大排序. //相当于数组的冒泡排序. #include <stdio.h> #include <stdlib.h> ...
随机推荐
- bzoj 4566: [Haoi2016]找相同字符
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...
- JavaBean转Map方法
Map<String, Object> fieldMap =new HashMap<String, Object>(); BeanInfo beanInfo = Introsp ...
- Nodejs的运行原理-架构篇
前言 本来是想只做一个Nodejs运行原理-科普篇,但是收到了不少私信,要我多分享一些更进阶,更详细的内容,所以我会在接下来的两个月里继续更新Nodejs运行原理. PS:此系列只做Nodejs的运行 ...
- windows 下的python 安装pycrypto
一般在官方网站下载pycrypto: https://www.dlitz.net/software/pycrypto/ 然后使用命令就可以安装成功了: python setup.py build ...
- js、jQuery、layer实现弹出层的打开、关闭
打开layer layer.open({ type: 2, title: '新增收货地址', shadeClose: true,//点击阴影关闭 shade: 0.8, area: ['900px', ...
- [编织消息框架][JAVA核心技术]动态代理应用1
前面几篇介绍,终于到了应用阶段啦,我们来做一个RPC来加强学过的知识 做基础核心时先确定解决什么问题,提供什么服务,同将来扩展等 rpc 分两部份,一个是调用者,另一方是服务提供者 调用者只关心那个服 ...
- 12.python进程\协程\异步IO
进程 创建进程 from multiprocessing import Process import time def func(name): time.sleep(2) print('hello', ...
- 3.移植uboot-使板卡支持nor、nand
在上一章,我们添加了nor,nand启动后,uboot启动出如下图所示: 上面的Flash: *** failed *** 是属于uboot第二阶段函数board_init_r()里的代码, 代码如下 ...
- angular4.0项目main.ts详解
main.ts负责引导整个angular应用的起点 // 导入enableProdMode用来关闭angular开发者模式 import { enableProdMode } from '@angul ...
- 企业级memcached缓存数据库结合php使用与web管理memcached
环境 [root@cache01 ~]# cat /etc/redhat-release CentOS Linux release (Core) [root@cache01 ~]# uname -a ...