C语言 链表的使用(链表的增删查改,链表逆转,链表排序)
- //链表的使用
- #define _CRT_SECURE_NO_WARNINGS
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- //定义链表结构体
- struct LinkCode{
- int num;
- char sname[];
- struct LinkCode * linknext;
- };
- //静态链表
- void Linkone(){
- struct LinkCode n1, n2, n3, n4, n5;
- struct LinkCode * head = NULL;
- //初始化变量
- n1.num = ;
- sprintf(n1.sname, "小明");
- n1.linknext = &n2;
- n2.num = ;
- sprintf(n2.sname, "小红");
- n2.linknext = &n3;
- n3.num = ;
- sprintf(n3.sname, "小芳");
- n3.linknext = &n4;
- n4.num = ;
- sprintf(n4.sname, "小刚");
- n4.linknext = &n5;
- n5.num = ;
- sprintf(n5.sname, "小志");
- n5.linknext = NULL;
- printf("\n==========静态链表============\n");
- //循环遍历----查询
- printf("\n==========查询============\n");
- for (head = &n1; head!= NULL; head = head->linknext)
- {
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //增加
- printf("\n==========增加============\n");
- struct LinkCode n6;
- n6.num = ;
- sprintf(n6.sname, "小雨");
- struct LinkCode n7;
- n7.num = ;
- sprintf(n7.sname, "小丽");
- //情景1,插入末尾
- printf("\n==========增加到末尾============\n");
- n5.linknext = &n6;
- n6.linknext = NULL;
- //循环遍历----查询
- for (head = &n1; head != NULL; head = head->linknext)
- {
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //情景2,插入到中间2后面
- printf("\n==========增加到中间============\n");
- struct LinkCode *px=NULL;
- for (head = &n1; head != NULL; head = head->linknext)
- {
- //注意for循环的执行顺序
- if (head->num==)
- {
- px = head->linknext;
- head->linknext = &n7;
- n7.linknext = px;
- }
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //修改
- printf("\n==========修改============\n");
- //把小红的num修改成99
- for (head = &n1; head != NULL; head = head->linknext)
- {
- //strcmp()函数 串比较 str1>str2,返回值 > 0;两串相等,返回0
- if (!strcmp(head->sname,"小红"))
- {
- head->num = ;
- }
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //删除
- printf("\n==========删除============\n");
- //删除num是7的节点
- for (head = &n1; head != NULL; head = head->linknext)
- {
- if (head->num==)
- {
- //找到该节点的地址,再次重新开始循环遍历
- px = head;
- }
- }
- for (head = &n1; head != NULL; head = head->linknext)
- {
- if (head->linknext==px)
- {
- //找到要删除节点的上一个节点
- head->linknext = px->linknext;
- }
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- printf("\n");
- }
- //动态链表
- 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 = ;
- sprintf(p1->sname, "小明1");
- p1->linknext = p2;
- p2->num = ;
- sprintf(p2->sname, "小红1");
- p2->linknext = p3;
- p3->num = ;
- sprintf(p3->sname, "小芳1");
- p3->linknext = p4;
- p4->num = ;
- sprintf(p4->sname, "小刚1");
- p4->linknext = p5;
- p5->num = ;
- sprintf(p5->sname, "小志1");
- p5->linknext = NULL;
- printf("\n==========查询============\n");
- //循环打印
- for (head = p1; head != NULL; head=head->linknext)
- {
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //增加
- printf("\n==========增加============\n");
- struct LinkCode *p6 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
- struct LinkCode *p7 = (struct LinkCode *)malloc(sizeof(struct LinkCode));
- p6->num = ;
- sprintf(p6->sname, "小雨1");
- p6->linknext = NULL;
- p7->num = ;
- sprintf(p7->sname, "小丽1");
- p7->linknext = NULL;
- //情景1,在末尾追加
- p5->linknext = p6;
- printf("\n==========增加(在末尾追加)============\n");
- //循环打印
- for (head = p1; head != NULL; head = head->linknext)
- {
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- printf("\n==========增加(在中间追加)============\n");
- 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("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //修改
- printf("\n==========修改============\n");
- p1->num = ;
- for (head = p1; head != NULL; head = head->linknext)
- {
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //删除
- printf("\n==========删除============\n");
- //删除节点num=4的节点
- for (head = p1; head != NULL; head = head->linknext)
- {
- if (head->num==)
- {
- //找到要删除的节点
- py = head;
- }
- }
- for (head = p1; head != NULL; head = head->linknext)
- {
- if (head->linknext==py)
- {
- head->linknext = py->linknext;
- free(py);
- //注意:动态链表的删除和静态链表的删除不同,静态链表创建是在栈中,而动态链表是用malloc()函数创建
- //所以动态链表在堆中,想要删除必须程序员手动用free()函数删除
- }
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- printf("\n");
- }
- //链表销毁
- void ClearLink(){
- printf("\n==========创建链表============\n");
- 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 = ;
- sprintf(p1->sname, "小明1");
- p1->linknext = p2;
- p2->num = ;
- sprintf(p2->sname, "小红1");
- p2->linknext = p3;
- p3->num = ;
- sprintf(p3->sname, "小芳1");
- p3->linknext = p4;
- p4->num = ;
- sprintf(p4->sname, "小刚1");
- p4->linknext = p5;
- p5->num = ;
- sprintf(p5->sname, "小志1");
- p5->linknext = NULL;
- printf("\n==========查询============\n");
- //循环打印
- for (head = p1; head != NULL; head = head->linknext)
- {
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //销毁链表(只要给我一个头结点的地址,我能够删除整个链表)
- printf("\n==========销毁链表============\n");
- //思路:一个个删除,保留第一个,删除第二个,把第三个重新连接成第二个
- 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("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //此时再删除第一个
- free(head);
- printf("\n头结点的指针地址%x", head);
- }
- //链表逆转
- void sort(){
- printf("\n==========创建链表============\n");
- 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 = ;
- sprintf(p1->sname, "小明1");
- p1->linknext = p2;
- p2->num = ;
- sprintf(p2->sname, "小红1");
- p2->linknext = p3;
- p3->num = ;
- sprintf(p3->sname, "小芳1");
- p3->linknext = p4;
- p4->num = ;
- sprintf(p4->sname, "小刚1");
- p4->linknext = p5;
- p5->num = ;
- sprintf(p5->sname, "小志1");
- p5->linknext = NULL;
- printf("\n==========查询============\n");
- //循环打印
- for (head = p1; head != NULL; head = head->linknext)
- {
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //链表逆转(只给头结点的地址)
- printf("\n==========链表逆转============\n");
- //思路;存储第一个的地址,让第一个的下一个是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("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- }
- //链表排序(方法1)
- //方法1:交换2个元素的位置
- //缺点:理解复杂,操作麻烦
- //链表的冒泡排序与数组有巨大区别
- //数组每个元素都可以单独确定,a[1]就是第二个元素
- //但是链表他的每个元素都是由他的上一个元素确定,不存在有多少个元素的概念,只是上一次可以找到下一个
- void Sort2(){
- printf("\n==========创建链表============\n");
- 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 = ;
- sprintf(p1->sname, "小明1");
- p1->linknext = p2;
- p2->num = ;
- sprintf(p2->sname, "小红1");
- p2->linknext = p3;
- p3->num = ;
- sprintf(p3->sname, "小芳1");
- p3->linknext = p4;
- p4->num = ;
- sprintf(p4->sname, "小刚1");
- p4->linknext = p5;
- p5->num = ;
- sprintf(p5->sname, "小志1");
- p5->linknext = NULL;
- printf("\n==========查询============\n");
- //循环打印
- for (head = p1; head != NULL; head = head->linknext)
- {
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //链表排序(只给头结点的地址)---由小到大
- printf("\n==========链表排序============\n");
- //思路;定义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 = ;
- 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("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- }
- //链表排序(方法2)
- //方法1:交换2个元素的内容,不改变链表节点的位置,只是内容的交换
- //优点:操作简单,通俗易懂
- void Sort3(){
- printf("\n==========创建链表============\n");
- 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 = ;
- sprintf(p1->sname, "小明1");
- p1->linknext = p2;
- p2->num = ;
- sprintf(p2->sname, "小红1");
- p2->linknext = p3;
- p3->num = ;
- sprintf(p3->sname, "小芳1");
- p3->linknext = p4;
- p4->num = ;
- sprintf(p4->sname, "小刚1");
- p4->linknext = p5;
- p5->num = ;
- sprintf(p5->sname, "小志1");
- p5->linknext = NULL;
- printf("\n==========查询============\n");
- //循环打印
- for (head = p1; head != NULL; head = head->linknext)
- {
- printf("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- //链表排序(只给头结点的地址)---由小到大
- printf("\n==========链表排序============\n");
- 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<py就会发生交换
- //导致当2是最小元素的时候,他必须先跟前面比他大的所有元素,把自己变成最大,并非单单与最大元素进行交换
- //也就是小元素会不断的被推到最前面
- if (px->num<py->num)
- {
- 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("\nnum=%d,sname=%s,linknext=%x", head->num, head->sname, head->linknext);
- }
- }
- void main(){
- //Linkone();
- //LinkTwo();
- //ClearLink();
- //sort();
- //Sort2();
- Sort3();
- system("pause");
- }
C语言 链表的使用(链表的增删查改,链表逆转,链表排序)的更多相关文章
- DataGridView绑定泛型List时,利用BindingList来实现增删查改
DataGridView绑定泛型List时,利用BindingList来实现增删查改 一. DataGridView绑定泛型List的种种 1.DataGridView数据绑定对比(DataTa ...
- 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...
- 8天学通MongoDB——第二天 细说增删查改
原文地址:http://www.cnblogs.com/huangxincheng/archive/2012/02/19/2357846.html 看过上一篇,相信大家都会知道如何开启mongodb了 ...
- 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性
基于.net的分布式系统限流组件 在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...
- 在MVC中使用泛型仓储模式和依赖注入实现增删查改
标签: 原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository ...
- golang使用json格式实现增删查改
需求和思路 在一般的小项目或者一个小软件,例如客户端之类的小程序中,可能会需要数据的持久化.但是使用一般的数据库(Mysql)之类的不合适.使用sqlite3这种嵌入式的是个较好的方法,但是Go语言中 ...
- 学习记录——使用PHP实现数据增删查改等基本功能(前后端分离)
萌新初次学习服务器端语言,分享学习经验 实现功能:1.显示数据表 2.对数据进行分页 3.对数据进行增删查改 由于本萌新采用前后端完全分离方案,所以数据传输用的ajax,为了提高代码的复用 ...
- 3.EF 6.0 Code-First实现增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-entity-framework-5-0-code- ...
- 4.在MVC中使用仓储模式进行增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-using-the-repository-pattern-in-mvc/ 系列目录: ...
- 5.在MVC中使用泛型仓储模式和工作单元来进行增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...
随机推荐
- 【转】Android 语言切换过程分析
最近在看一个bug,系统切换语言后,本来退到后台的音乐,会在通知栏上显示通知.为了解决这个bug,我学习了下android的语言切换流程,也参考了大量其他人的资料.(主要参考了http://blog. ...
- Android表单UI及相应控件的事件处理
一.Toast Toast是一种轻量级的提示工具,可显示一行文本对用户的操作进行提示响应 用法:Toast.makeText(context,text,time).show(); context:上下 ...
- 异步get请求之Block方法
#import "ViewController.h" #import "Header.h" @interface ViewController ()<NS ...
- OC中结构体作为对象属性
在OC中结构体有时候也作为对象的属性 类的定义 #import <Foundation/Foundation.h> typedef struct{ int year; int month; ...
- JSPatch一些容易犯错的地方
JSPatch一些自己使用后的发现: 1.JS不区分整数和浮点数.解析字典以后的value不需要通过 floatValue等方法转换,而是自动就转换成对应的数据类型. 2.nil在JSPatch中 不 ...
- poj邮局1160
题目是给出V个村庄,取出P个做为邮局,要求每个村庄到邮局的距离和最小. 先考虑只有一个邮局的情况,不管你怎么放邮局和最小的情况总是在中点的位置. 再来考虑P>1的情况: 假设P-1个邮局已经选好 ...
- System Center的一些资料收集
MS 的 system center 中文首页 http://www.microsoft.com/zh-cn/server-cloud/system-center/default.aspx 英文首页 ...
- PS网页设计教程XXIV——从头设计一个漂亮的网站
作为编码者,美工基础是偏弱的.我们可以参考一些成熟的网页PS教程,提高自身的设计能力.套用一句话,“熟读唐诗三百首,不会作诗也会吟”. 本系列的教程来源于网上的PS教程,都是国外的,全英文的.本人尝试 ...
- 在Jena框架下基于MySQL数据库实现本体的存取操作
在Jena框架下基于MySQL数据库实现本体的存取操作 转自:http://blog.csdn.net/jtz_mpp/article/details/6224311 最近在做一个基于本体的管理系统. ...
- ETL from hadoop to vertica
根据项目需要,我做了一个POC(proof of concept),XML TXT的数据从HADOOP 引入到VERTICA. 我采用的方案是pig,具体信息可以参加vertica官方的文档. Acc ...