C语言 链表的使用(链表的增删查改,链表逆转,链表排序)

发布时间:2021-10-14 08:44:53

//链表的使用

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include

//定义链表结构体
struct LinkCode{
int num;
char sname[50];
struct LinkCode * linknext;
};

//静态链表
void Linkone(){
struct LinkCode n1, n2, n3, n4, n5;
struct LinkCode * head = NULL;
//初始化变量
n1.num = 1;
sprintf(n1.sname, "小明");
n1.linknext = &n2;

n2.num = 2;
sprintf(n2.sname, "小红");
n2.linknext = &n3;

n3.num = 3;
sprintf(n3.sname, "小芳");
n3.linknext = &n4;

n4.num = 4;
sprintf(n4.sname, "小刚");
n4.linknext = &n5;

n5.num = 5;
sprintf(n5.sname, "小志");
n5.linknext = NULL;

printf("
==========静态链表============
");

//循环遍历----查询
printf("
==========查询============
");
for (head = &n1; head!= NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}


//增加
printf("
==========增加============
");
struct LinkCode n6;
n6.num = 6;
sprintf(n6.sname, "小雨");

struct LinkCode n7;
n7.num = 7;
sprintf(n7.sname, "小丽");

//情景1,插入末尾
printf("
==========增加到末尾============
");
n5.linknext = &n6;
n6.linknext = NULL;
//循环遍历----查询
for (head = &n1; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

//情景2,插入到中间2后面
printf("
==========增加到中间============
");
struct LinkCode *px=NULL;
for (head = &n1; head != NULL; head = head->linknext)
{
//注意for循环的执行顺序
if (head->num==2)
{
px = head->linknext;
head->linknext = &n7;
n7.linknext = px;
}
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

//修改
printf("
==========修改============
");
//把小红的num修改成99
for (head = &n1; head != NULL; head = head->linknext)
{
//strcmp()函数 串比较 str1>str2,返回值 > 0;两串相等,返回0
if (!strcmp(head->sname,"小红"))
{
head->num = 99;
}
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

//删除
printf("
==========删除============
");
//删除num是7的节点
for (head = &n1; head != NULL; head = head->linknext)
{
if (head->num==7)
{
//找到该节点的地址,再次重新开始循环遍历
px = head;
}
}

for (head = &n1; head != NULL; head = head->linknext)
{
if (head->linknext==px)
{
//找到要删除节点的上一个节点
head->linknext = px->linknext;
}
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}


printf("
");
}

//动态链表
void LinkTwo(){
struct LinkCode * head, *p1, *p2, *p3, *p4, *p5;
head = p1 = p2 = p3 = p4 = p5 = NULL;
//先分配内存
p1 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p2 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p3 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p4 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p5 = (struct LinkCode *)malloc(sizeof(struct LinkCode));

p1->num = 1;
sprintf(p1->sname, "小明1");
p1->linknext = p2;

p2->num = 2;
sprintf(p2->sname, "小红1");
p2->linknext = p3;

p3->num = 3;
sprintf(p3->sname, "小芳1");
p3->linknext = p4;

p4->num = 4;
sprintf(p4->sname, "小刚1");
p4->linknext = p5;

p5->num = 5;
sprintf(p5->sname, "小志1");
p5->linknext = NULL;

printf("
==========查询============
");
//循环打印
for (head = p1; head != NULL; head=head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

//增加
printf("
==========增加============
");

struct LinkCode *p6 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
struct LinkCode *p7 = (struct LinkCode *)malloc(sizeof(struct LinkCode));

p6->num = 6;
sprintf(p6->sname, "小雨1");
p6->linknext = NULL;

p7->num = 7;
sprintf(p7->sname, "小丽1");
p7->linknext = NULL;

//情景1,在末尾追加
p5->linknext = p6;
printf("
==========增加(在末尾追加)============
");
//循环打印
for (head = p1; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

printf("
==========增加(在中间追加)============
");
struct LinkCode *py = NULL;
//情景2,在中间追加(追加在小红后面)
for (head = p1; head != NULL; head = head->linknext)
{
if (!strcmp(head->sname, "小红1"))
{
py = head->linknext;
head->linknext = p7;
p7->linknext = py;
}
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

//修改
printf("
==========修改============
");
p1->num = 99;
for (head = p1; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

//删除
printf("
==========删除============
");
//删除节点num=4的节点
for (head = p1; head != NULL; head = head->linknext)
{
if (head->num==4)
{
//找到要删除的节点
py = head;
}
}
for (head = p1; head != NULL; head = head->linknext)
{
if (head->linknext==py)
{
head->linknext = py->linknext;
free(py);
//注意:动态链表的删除和静态链表的删除不同,静态链表创建是在栈中,而动态链表是用malloc()函数创建
//所以动态链表在堆中,想要删除必须程序员手动用free()函数删除
}
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

printf("
");
}

//链表销毁
void ClearLink(){
printf("
==========创建链表============
");
struct LinkCode * head, *p1, *p2, *p3, *p4, *p5;
head = p1 = p2 = p3 = p4 = p5 = NULL;
//先分配内存
p1 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p2 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p3 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p4 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p5 = (struct LinkCode *)malloc(sizeof(struct LinkCode));

p1->num = 1;
sprintf(p1->sname, "小明1");
p1->linknext = p2;

p2->num = 2;
sprintf(p2->sname, "小红1");
p2->linknext = p3;

p3->num = 3;
sprintf(p3->sname, "小芳1");
p3->linknext = p4;

p4->num = 4;
sprintf(p4->sname, "小刚1");
p4->linknext = p5;

p5->num = 5;
sprintf(p5->sname, "小志1");
p5->linknext = NULL;

printf("
==========查询============
");
//循环打印
for (head = p1; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

//销毁链表(只要给我一个头结点的地址,我能够删除整个链表)
printf("
==========销毁链表============
");
//思路:一个个删除,保留第一个,删除第二个,把第三个重新连接成第二个
struct LinkCode *pt = NULL;
//循环打印
while (p1->linknext!=NULL){
//获取第二个的地址
pt = p1->linknext;
//把第三个的地址放到第一个后面
p1->linknext = p1->linknext->linknext;
//删除第二个
free(pt);
}
//当p1->linknext!=NULL时,表示整个链表只剩下第一个了
//循环打印
for (head = p1; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}
//此时再删除第一个
free(head);
printf("
头结点的指针地址%x", head);
}

//链表逆转
void sort(){
printf("
==========创建链表============
");
struct LinkCode * head, *p1, *p2, *p3, *p4, *p5;
head = p1 = p2 = p3 = p4 = p5 = NULL;
//先分配内存
p1 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p2 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p3 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p4 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p5 = (struct LinkCode *)malloc(sizeof(struct LinkCode));

p1->num = 1;
sprintf(p1->sname, "小明1");
p1->linknext = p2;

p2->num = 2;
sprintf(p2->sname, "小红1");
p2->linknext = p3;

p3->num = 3;
sprintf(p3->sname, "小芳1");
p3->linknext = p4;

p4->num = 4;
sprintf(p4->sname, "小刚1");
p4->linknext = p5;

p5->num = 5;
sprintf(p5->sname, "小志1");
p5->linknext = NULL;

printf("
==========查询============
");
//循环打印
for (head = p1; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

//链表逆转(只给头结点的地址)
printf("
==========链表逆转============
");
//思路;存储第一个的地址,让第一个的下一个是NULL,第二个的下一个是原来的第一个,第三个下一个是原来的第二个
head = p1;
struct LinkCode *px = head;//头结点
struct LinkCode *py = head->linknext;//第二个节点
struct LinkCode *pz = NULL;
while (py!=NULL){
pz = py->linknext;//第三个节点
//开始逆转
py->linknext = px;//将第二个节点的下个节点赋值为第一个节点的地址
//开始将所有指针向前移动1位
px = py;//将第一个节点向前移动1位(移动到第二个节点的位置)
py = pz;//将第二个节点向前移动1位(移动到第三个节点的位置)
//此时再次进入循环 pz = py->linknext; 这会将第三个节点的值变成第四个节点
//当py->linknext==NULL(即pz =NULL)的时候;表明此时py已经是链表最后一个节点了,
//那么py->linknext的值就必须是链表倒数第二个的地址,所以还需要再循环1次,给py->linknext赋值,
//再次经过py = pz;此时py==NULL;
}
//这个时候原来的第一个节点的linknext属性的值还是第二个节点的地址,,这是错误的,应该置为空
head->linknext = NULL;
//此时px就是原来链表最后一个节点的地址,因为head必须是头结点并且链表已经逆转了,
//所以head的值不能是原来的第一个节点,而应该是原来链表最后一个节点的地址
head = px;
//循环打印
for (head; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}


}

//链表排序(方法1)
//方法1:交换2个元素的位置
//缺点:理解复杂,操作麻烦
//链表的冒泡排序与数组有巨大区别
//数组每个元素都可以单独确定,a[1]就是第二个元素
//但是链表他的每个元素都是由他的上一个元素确定,不存在有多少个元素的概念,只是上一次可以找到下一个
void Sort2(){
printf("
==========创建链表============
");
struct LinkCode * head, *p1, *p2, *p3, *p4, *p5;
head = p1 = p2 = p3 = p4 = p5 = NULL;
//先分配内存
p1 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p2 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p3 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p4 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p5 = (struct LinkCode *)malloc(sizeof(struct LinkCode));

p1->num = 30;
sprintf(p1->sname, "小明1");
p1->linknext = p2;

p2->num = 12;
sprintf(p2->sname, "小红1");
p2->linknext = p3;

p3->num = 9;
sprintf(p3->sname, "小芳1");
p3->linknext = p4;

p4->num = 4;
sprintf(p4->sname, "小刚1");
p4->linknext = p5;

p5->num = 2;
sprintf(p5->sname, "小志1");
p5->linknext = NULL;

printf("
==========查询============
");
//循环打印
for (head = p1; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

//链表排序(只给头结点的地址)---由小到大
printf("
==========链表排序============
");
//思路;定义3个变量,因为链表无法通过当前元素获取上一个元素,所以只能用一个变量将上一个变量的地址记录下来

//px--代表第一个元素,py代表第二个元素,pz代表第三个元素
//参与比较的是py与pz
struct LinkCode * px, *py, *pz;
//初始化指针,防止后面出错
px = py = pz=NULL;
//在比较链表前2个元素的时候,第一个元素没有上一个元素,所以px=py=head
px =py= head=p1;


//冒泡排序,每循环一次,会将一个最大值移动到末尾,每移动一次,需要移动的元素就会少一个
//一共5个元素,移动4次后,最大的元素都已经放到链表末尾
int index = 4;
while (index){//外层循环
//获取第三个元素的值
pz = py->linknext;
if (py->num>pz->num)
{
//如果第一个节点的num比第二个大,则要求交换位置
//1.把第一个节点的下个节点属性赋值为第三个节点的地址
//此时px是第一个元素
px->linknext = pz;
//2.把第二个节点的下个节点属性赋值为第四个节点的地址
py->linknext = pz->linknext;
//3.把第三个节点的下个节点属性赋值为第二个节点的地址
pz->linknext = py;
//第一组交换完成
//4.将所有节点向前移动一位,这里px已经不是第一个元素了,他往前移动1位
//因为要确定头结点的值,所以前2个元素的比较,必须单独提取出来
head = px = pz;
}
do{
pz = py->linknext;
if (py->num>pz->num)
{
//如果第一个节点比第二个大,则要求交换位置
//1.把第一个节点的下个节点属性赋值为第三个节点的地址
px->linknext = pz;
//2.把第二个节点的下个节点属性赋值为第四个节点的地址
py->linknext = pz->linknext;
//3.把第三个节点的下个节点属性赋值为第二个节点的地址
pz->linknext = py;
//第一组交换完成
//4.将所有节点向前移动一位
px = pz;
}
else{
//如果大小顺序正确,3个元素都需要再向前移动1位;
//把第二个元素赋值给原来第一个元素
px = py;
//把第三个元素赋值给原来第二个元素
py = pz;
}
} while (py->linknext != NULL);//判断第三个元素是否是空
//再次初始化
//因为此时px,py,pz都已经移动到链表末尾
px = py = head;
pz = py->linknext;
index--;
}




//循环打印
for (head; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}


}

//链表排序(方法2)
//方法1:交换2个元素的内容,不改变链表节点的位置,只是内容的交换
//优点:操作简单,通俗易懂
void Sort3(){
printf("
==========创建链表============
");
struct LinkCode * head, *p1, *p2, *p3, *p4, *p5;
head = p1 = p2 = p3 = p4 = p5 = NULL;
//先分配内存
p1 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p2 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p3 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p4 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
p5 = (struct LinkCode *)malloc(sizeof(struct LinkCode));

p1->num = 3;
sprintf(p1->sname, "小明1");
p1->linknext = p2;

p2->num = 12;
sprintf(p2->sname, "小红1");
p2->linknext = p3;

p3->num = 9;
sprintf(p3->sname, "小芳1");
p3->linknext = p4;

p4->num = 4;
sprintf(p4->sname, "小刚1");
p4->linknext = p5;

p5->num = 2;
sprintf(p5->sname, "小志1");
p5->linknext = NULL;

printf("
==========查询============
");
//循环打印
for (head = p1; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

//链表排序(只给头结点的地址)---由小到大
printf("
==========链表排序============
");

struct LinkCode *px = NULL;
struct LinkCode *py = NULL;
struct LinkCode sz;

for (px = head = p1; px != NULL; px = px->linknext)
{
for (py = head = p1; py != NULL; py = py->linknext)
{
//双循环
//外循环的一个元素跟其他5个元素相比较,只要px //导致当2是最小元素的时候,他必须先跟前面比他大的所有元素,把自己变成最大,并非单单与最大元素进行交换
//也就是小元素会不断的被推到最前面
if (px->numnum)
{
sz.num = px->num;
px->num = py->num;
py->num = sz.num;

sprintf(sz.sname, px->sname);
sprintf(px->sname, py->sname);
sprintf(py->sname, sz.sname);
}
}
}
//循环打印
for (head = p1; head != NULL; head = head->linknext)
{
printf("
num=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
}

}

void main(){
//Linkone();
//LinkTwo();
//ClearLink();
//sort();
//Sort2();
Sort3();

system("pause");
}

?



?



?



?



?



?


?


相关文档

  • 前端面试题目整理??css篇
  • C++灵魂指针详解
  • 关于小学生五好小公民的演讲稿
  • 艾玛抢戏石头姐,出演《小妇人》
  • 【必备】大学学习计划3篇
  • 特殊游戏特殊体验班会教案
  • 建议书保护环境作文精选五篇范文
  • 校招百度两面,大数据面试经历:数据分析与数据挖掘,附面试题
  • 个人简历护理个人推荐信
  • 蝶恋花?晓日窥轩双燕语翻译及赏析
  • 发给客户的祝福话语
  • 咽喉炎的介绍 咽喉炎吃什么
  • MySql5.5msi详细安装教程
  • 儿童多动症原因需要大家堤防 多种典型的孩子多动症的原因
  • 老卢其人
  • 专项委托代理合同通用版
  • 软件测试的基本流程(详细)
  • 社会主义新农村建设基本现状调研报告
  • 春节期间施工现场安全措施
  • 幼儿园英语教师个人学期总结说明
  • 属狗和属马做生意合不合财
  • 孝敬老人作文500字
  • 扣字开头的成语接龙大全
  • 信号与系统(上)
  • 如何写出满分作文?高考英语作文万能模版
  • DLNA技术浅析
  • 幼儿园教师工作体会感言
  • 秋季养生原则
  • 这是怎么回事呢上一句
  • 一种std::string的格式化方法
  • 猜你喜欢

  • 七年级英语下册Unit3Howdoyougettoschool第5课时SectionB(2a_3b)*题课件新版人教新目标版
  • 部编人教版三年级《道德与法治》下册《生活离不开规则》教案
  • 幼儿园大清洗大清整大扫除活动总结
  • 2020版八年级上册初二数学北师大版全套课件作业本第6章第5课时数据的离散程度
  • 北京星写教育科技有限公司企业信用报告-天眼查
  • 2018年江苏省徐州市中考数学二模试卷及解析
  • 高中记忆 难忘的高中生活1900字
  • 某地小厂区安保系统方案设计施工图
  • 公司企业文化建设方案
  • 【学案导学设计】高中物理 第1章 电磁感应与现代生活章末检测卷 沪科版选修3-2
  • 中西药联合治疗病态窦房结综合征临床观察
  • 2019年年秋安徽专版沪科版八年级上册数学习题课件:1324三角形的外角性质(共27张PPT)语文
  • 大连兴林科技有限公司企业信用报告-天眼查
  • 【高中课件】人教A版高中数学必修4231*面向量基本定理课件ppt.ppt
  • 高一数学知识点总结--必修5[1]
  • (中企智业)2013-2018年中国第三方环境检测行业发展分析
  • 与众不同的老师作文700字
  • 哪些是德国留学要求
  • 汽车驾驶考试科目一新题第3章
  • 2019-2020学年人教版初二英语上册期中测试卷(附答案)
  • 五岁脑筋急转弯
  • 2019年3.15消费者权益日活动策划方案
  • 女人什么年龄吃阿胶好年轻女生可以吃阿胶吗
  • 幼儿教师的生活质量与职业倦怠
  • 2008中国大学教育学本科A
  • 陕西百姓乐生活用品便利店有限公司七九五店企业信用报告-天眼查
  • 精品同学会主持词四篇
  • 最新整理智能家居设计方案.docx
  • 我心中的真善美
  • XX年护士年度工作总结最新范文
  • 长沙嘉都房地产经纪有限公司企业信用报告-天眼查
  • 赞美人物的诗歌有哪些
  • 浅谈高校干部人事档案材料收集、鉴别及应对措施
  • 并流多通道管壳式换热器壳程流场分布
  • 【工作总结范文】小学上学期教科研工作检查及评价分析研究性工作总结
  • 关于钢铁企业余热资源的回收与利用分析
  • 祁阳县永兴爆破服务有限公司企业信用报告-天眼查
  • 浙江省语文高考二轮复*自主加餐练:阅读组合增分练12 文言文古诗歌名句默写含解析
  • 四川省内江市2016年中考数学试卷(解析版)
  • 论亚洲代表性国家宪法实践权威的达致(一)
  • 【语文专题推荐】同步综合复*小学语文小升初模拟试卷III卷
  • 行政判决的反射效力 武汉大学法学院教授
  • 电脑版