c语言链表增加新节点,C语言 链表的创建,以及节点的增加和删除
第一次写博客,如有错误还请指正…………
今天下午倒腾了一下的链表,感觉链表就是一个小型的,用于简单的小程序的用户信息存储和管理还是很方便的。
下面为方便起见,以学生信息为例:
链表采用了动态分配的办法为一个结构分配内存空间。每一次分配一块空间可用来存放一个学生的数据,我们可称之为一个结点。有多少个学生就应该申请分配多少块内存空间,也就是说要建立多少个结点。当然用结构数组也可以完成上述工作,但如果预先不能准确把握学生人数,也就无法确定数组大小。而且当学生留级、退学之后也不能把该元素占用的空间从数组中释放出来。用动态存储的方法可以很好地解决这些问题。有一个学生就分配一个结点,无须预先确定学生的准确人数,某学生退学,可删去该结点,并释放该结点占用的存储空间。从而节约了宝贵的内存资源。另一方面,用数组的方法必须占用一块连续的内存区域。而使用动态分配时,每个结点之间可以是不连续的(结点内是连续的)。结点之间的联系可以用指针实现。 即在结点结构中定义一个成员项用来存放下一结点的首地址,这个用于存放地址的成员,常把它称为指针域。
可在第一个结点的指针域内存入第二个结点的首地址,在第二个结点的指针域内又存放第三个结点的首地址,如此串连下去直到最后一个结点。最后一个结点因无后续结点连接,其指针域可赋为0。这样一种连接方式,在数据结构中称为“链表”。
下面给出一个简单的例子,包含链表的创建,
#include
#include
#define len sizeof (struct stu)
/*
head为(伪)头指针,pbefore为指向两相邻结点的前一结点的指针变量。pafter为后一结点的指针变量。
*/
//定义学生个数
int n=4;
//定义链表结构体
typedef struct stu{
int num;
int age;
struct stu *next;
}type;
/*定义删除函数:删除所选中的节点*/
void delete(type *head,int number)
{
int i;
type *list=head;
type *tp=null;
//这里循环n+1次,是因为包含头节点在内总共有n+1个节点
for(i=0;i
printf("the next:%ld\n",(long)list->next);
if(list->num==number){
if(list->next==0){
tp->next=0;
break;
}else{
tp->next=list->next;
break;
}
}
tp=list;// 临时指针指向的是前一节点
list=list->next; //继续判断下一节点
}
}
/*定义查询函数:显示链表中所有信息*/
void query(type *head)
{
type *list=head;
while(list)
{
printf("%d,%d\n",list->num,list->age);
printf("the next:%ld\n",(long)list->next);
list=list->next;
}
}
int main()
{
//这是定义的真正的头节点
struct stu *head;
head->num=0;
head->age=0;
struct stu *thead,*pbefore,*pafter;
int i;
for(i=0;inum,&pafter->age);
if(i==0) pbefore=thead=pafter; //第一次循环,直接设置头节点
else pbefore->next=pafter;
//这里的pbefore其实是上一轮循环的after赋予的,所以是 “前一个节点”
//注意:这里改动的不是pbefore,而是pbefore指向的内存里的数据
pafter->next=null; // 将最后的指针域清零,赋给pbefore,即前节点
pbefore=pafter;// 这里pbefore指向了新的内存,也就是下一个节点
// 强调一下,pbefore只是一个指针
}
head->next=thead;
query(head);
int number;
printf("you want to delete:");
scanf("%d",&number);
delete(head,number);
query(head);
return 0;
}
以上程序包含了一个节点数为n+1的链表(n个学生节点和1个头节点,因为头节点没有数据域)。如果没有提前定义头节点,则第一个学生的节点则为头节点,这样就导致这个头节点无法删除。
上图可以看出,如果直接删除了头节点,会发生段错误。
现在我们在链表的尾部增加一个节点
#include
#include
#define len sizeof (struct stu)
typedef struct stu{
int num;
int age;
struct stu *next;
}type;
int n=4;
/*增加节点函数:返回新的尾部节点地址*/
type *add(type* tail)
{
type *new;
new=(type*) malloc(len);
printf("input the new num and age\n");
scanf("%d%d",&new->num,&new->age);
tail->next=new;
printf("tail:%ld",(long)tail);
new->next=null;//缺了这一句,新的节点数据就显示不出了
tail=new;
printf("new tail:%ld",(long)tail);
return tail;
}
/*删除节点函数*/
void delete(type *head,type* tail,int number)
{
int i;
type *list=head;
type *tp=null;
for(i=0;i
// printf("the next:%ld\n",(long)list->next);
if(list->num==number){
if(list->next==0){
tp->next=0;
tail=tp;//若尾部节点被删除,则更新尾部节点
break;
}else{
tp->next=list->next;
break;
}
}
tp=list;// 临时指针指向的是前一节点
list=list->next; //继续判断下一节点
}
}
/*查询函数:显示所有节点数据*/
void query(type *head)
{
type *list=head;
while(list)
{
printf("%d,%d\n",list->num,list->age);
//printf("the next:%ld\n",(long)list->next);
list=list->next;
}
}
int main()
{
//初始化头节点以及尾部节点
struct stu *head;
struct stu *tail;
head->num=0;
head->age=0;
struct stu *thead,*pbefore,*pafter;
int i;
for(i=0;inum,&pafter->age);
if(i==0) pbefore=thead=pafter;
else pbefore->next=pafter;
pafter->next=null;
pbefore=pafter;
}
tail=pafter;
printf(" tail:%ld",(long)tail);
head->next=thead;
query(head);
int number;
printf("you want to delete:");
scanf("%d",&number);
delete(head,tail,number);
query(head);
tail=add(tail);
query(head);
tail=add(tail);
query(head);
return 0;
}
这里我们需要定义尾部节点,并且增加后要对尾部节点进行更新,方便再次在链表后面插入节点,注意:不要忘了给新的节点分配内存,否则会报段错误,因为你给并没有分配内存的结构体赋值了。
new=(type*) malloc(len);
另外不要忘了给新的尾部节点的指针域设置为null。
new->next=null;
以上是增加了两个节点的例子,运行结果如下
可以看到,增加的节点已经显示出来了。
c语言链表增加新节点,C语言 链表的创建,以及节点的增加和删除相关推荐
- js添加多个子节点_JS创建DOM节点-使用document.createElement()创建子节点或同级节点...
在一个Web页面中,需要弹出一个提示信息显示给用户.基于这个需求,要使用document.createElement()创建一个DOM节点.创建完节点后,还要使用appendChild()或inser ...
- zk pivottable java_zookeeper节点类型和java客户端创建zk节点
0 znode节点类型: Znode有两种类型,短暂的(ephemeral)和持久的(persistent) Znode的类型在创建时确定并且之后不能再修改 短暂znode的客户端会话结束时,zook ...
- linux内核创建节点,Linux内核驱动自动创建设备节点文件
Linux下生成驱动设备节点文件的方法有3个:1.手动mknod:2.利用devfs:3.利用udev 在刚开始写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点,实际上L ...
- c语言自动输入新数组,c语言 向有序数组中插入一个数,保持原顺序不变,将新数组输出...
#include"stdafx.h" #include intmain() { intm,n,i,j,h; inta[17]={1,5,9,14,23,34,45,56,67,78 ...
- 中国电力出版社C语言书答案,新概念C语言教程第六章答案张基温著中国电力出版社出版.doc...
6.1结构体类型的定义与实例化 探索验证:(测量结构所占有的存储空间) 程序编程: #include struct Data{ int year; int month; int day; }; str ...
- js添加多个子节点_javascript如何创建子节点
学习完HTM年据业会效近轻业务进果近轻业务进果近轻业L+css后,我并没有直接去学习HTML5和css3,而是开始学习JavaScript,现在就是jQuery基础也懂一点,js也懂一点,css3也懂 ...
- 【手写 Vue2.x 源码】第十九篇 - 根据 vnode 创建真实节点
一,前言 上篇,根据 render 函数,生成 vnode,主要涉及以下几点: 封装 vm._render 返回虚拟节点 _s,_v,_c的实现 本篇,根据 vnode 虚拟节点渲染真实节点 二,根据 ...
- 【Groovy】自定义 Xml 生成器 BuilderSupport ( 创建 XmlNode 节点 | 管理 XmlNode 节点并将根节点转为 Xml 信息 | 完整代码示例 )
文章目录 一.创建 XmlNode 节点 二.管理 XmlNode 节点并将根节点转为 Xml 信息 三.完整代码示例 1.自定义 Xml 生成器 MyBuilderSupport 2.Xml 节点封 ...
- JavaScript创建页面节点
如果你看到前面的阴影,别怕,那是因为你背后有阳光 下面是对JavaScript中创建页面节点的整理,希望可以帮助到有需要的小伙伴 创建页面节点 1.创建元素节点 Document对象提供了create ...
最新文章
- 部署SQL AZURE的客户端管理工具,云计算体验之二
- Java 常用构建对象的三种方式
- 阿里开源Mysql分布式中间件:Cobar
- JQuery环境配置
- SAP AUTHORITY-CHECK 的使用
- [云炬创业基础笔记]第二章创业者测试1
- 第一个jfinal的样例
- mysql 命令 pdf_MySQL命令文档 PDF 下载
- world文档粘贴图片进去看不到
- 经验:Windows To Go准备工作
- webpack2入门概念
- 【C++ STL学习之二】容器vector大总结
- 几个容器网络相关问题的分析和解决总结
- 10个用Console来Debug的高级技巧
- 深度图补全-depth inpainting
- pygarm windows 安装_飘云阁(PYG官方) Windows PowerShell实战指南(第2版)PDF - Powered by Discuz!...
- python贪吃蛇_python贪吃蛇
- 无法找到c语言dll入口点,c# – 无法在DLL中找到入口点
- 【搜索引擎】Apache Solr 神经搜索
- Android图形显示系统原理