数据结构:链表(c语言)

1.链表简介:
链表和数组一样,都是存储数据,链表是非连续,非顺序的存储结构
链表是灵活的内存动态管理(随机分配空间),删除创建结点非常方便
链表组成:由一系列结点组成
链表结点:实际上是结构体变量

typedef struct LINKNODE
{int data;// 数据域struct _LINKNODE *next;// 指针域
}Link_Node;

链表结点包含两个部分:
1.存储数据元素的数据域
2.存储下一个结点地址的指针域

2.链表和数组的区别
数组:一次性分配连续的存储区域
优点:随机访问元素效率搞
缺点:开辟内存过大时,易分配失败;插入和删除效率低下
链表:无需一次性分配连续的存储空间,只需要分配n块结点存储区域,通过指针建立联系
优点:不需要一次性分配连续的存储区域;删除和插入效率高
缺点:随机访问元素效率低

3.静态链表:是在初始化的时候就分配好足够的内存空间,存储空间是静态的,分配在栈上,模拟数组实现的,是顺序的存储结构

#include<stdio.h>
#include<string.h>
#include<stdlib.h>typedef struct LINKNODE{int data;struct LINKNODE *next;
}Link_Node;int main()
{Link_Node Node1={1,NULL};Link_Node Node2={2,NULL};Link_Node Node3={3,NULL};Node1.next=&Node2;Node2.next=&Node3;Node3.next=NULL;Link_Node *head=&Node1;while(head!=NULL){printf("data:[%d]\n",head->data);head=head->next;}return 0;
}

4.动态链表

#include<stdio.h>
#include<string.h>
#include<stdlib.h>typedef struct LINKNODE{int data;struct LINKNODE *next;
}Link_Node;int main()
{Link_Node *Node1=(Link_Node *)malloc(sizeof(Link_Node));Link_Node *Node2=(Link_Node *)malloc(sizeof(Link_Node));Link_Node *Node3=(Link_Node *)malloc(sizeof(Link_Node));Node1->data=1;Node2->data=2;Node3->data=3;Node1->next=Node2;Node2->next=Node3;Node3->next=NULL;Link_Node *head=&Node1;while(head!=NULL){printf("data:[%d]\n",head->data);head=head->next;}return 0;
}

5.带头链表和不带头链表
带头链表:固定一个结点作为头结点,不关心数据域,起一个标志位的作用,链表结点如何变化,此头结点固定不变
不带头结点:头结点不固定,所有结点都可以作为头,可以随机变化
6.链表按照类型又划分为:单向链表,双向链表,循环链表
7.链表的基本操作(基于单向链表)
1.创建链表结点域

typedef struct LINKNODE{int data;struct LINKNODE *next;
}Link_Node;

2.创建链表

Link_Node *Init_Link_Node()
{Link_Node *cur=NULL;//保存上一个结点 Link_Node *pNew=NULL;//辅助指针 Link_Node *head=NULL;//固定为头结点 //创建头结点 pNew=(Link_Node)malloc(sizeof(Link_Node));pNew->data=-1;pNew->next=NULL;head=pNew;cur=pNew;//head作为头结点,cur保存结点 //创建循环结点 int dataid; while(1){printf("请输入data id编号:");scanf("%d",&dataid);if(dataid<=0) break;else{//创建新结点 pNew=(Link_Node)malloc(sizeof(Link_Node));pNew->data=dataid;cur->next=pNew;//头结点(head)指向新结点 pNew->next=NULL;cur=pNew;//指针下移 }}return head;	
}

3.遍历链表

int Print_Link_Node(Link_Node *head)
{if(head==NULL) return -1;else{Link_Node *cur=head->next;printf("head->");while(cur!=NULL){printf("%d->",cur->data);cur=cur->next;} printf("NULL\n");//cur指向了NULL }	
}

4.在头部插入结点

void Init_Head_Link_Node(Link_Node *head,int dataid)
{if(head==NULL) return -1;else{Link_Node *cur=head->next;//保存第一个有效结点 Link_Node *pNew=(Link_Node *)malloc(sizeof(Link_Node));pNew->data=dataid;//建立关系 head->next=pNew;pNew->next=cur;}
}

5.尾部插入

void Init_Tail_Link_Node(Link_Node *head,int dataid)
{if(head==NULL) return -1;else{Link_Node *cur=head;//保存结点,获取最后一个结点 while(cur->next!=NULL){cur=cur->next;//结点后移 }Link_Node *pNew=(Link_Node *)malloc(sizeof(Link_Node));pNew->data=dataid;cur->next=pNew;pNew->next=NULL;		}	
}

6.指定位置

//找到data为num的前面插入,找不到就尾插 
void Init_Insert_Link_Node(Link_Node *head,int num,int dataid)
{if(head==NULL){return;}//一定记得判断headLink_Node *cur=head->next;//cur为第一个有效结点 Link_Node *pre=head;//pre保存cur的前一个结点 while(cur!=NULL){//此循环体是查找插入位置,找到则跳出循环 if(cur->next==num){break;} pre=pre->next; cur=cur->next;} Link_Node *pNew=(Link_Node *)malloc(sizeof(Link_Node));pNew->data=dataid;pre->next=pNew;pNew->next=cur; }

7.删除指定data第一个值

void Del_Link_Node(Link_Node *head,int dataid)
{if(head==NULL) return;Link_Node *cur=head->next;Link_Node *pre=head;int flag=0;while(cur!=NULL){if(cur->data==dataid){flag=1;pre->next=cur->next;free(cur);cur=NULL;break;}pre=pre->next;cur=cur->next;} if(flag==0){printf("没有找到%d的结点\n",dataid);}
}

8.释放链表

void Destroy_link_Node(Link_Node *head)
{link_Node *cur=head;while(cur->next!=NULL){head=head->next;free(cur);cur->next=NULL;cur=head;}printf("链表清空\n");
}

9.main函数

int main(int argc,char argv[])
{//创建链表 Link_Node *headLink_Node=Init_Link_Node();Print_Link_Node(headLink_Node);//头插法Init_Head_Link_Node(headLink_Node,1111);Print_Link_Node(headLink_Node);//尾插法Init_Tail_Link_Node(headLink_Node,2222); Print_Link_Node(headLink_Node);//查找插入Init_Insert_Link_Node(headLink_Node,4,3333);Print_Link_Node(headLink_Node);//删除Del_Link_Node(headLink_Node,2);Print_Link_Node(headLink_Node);//清空链表Destroy_Link_Node(headLink_Node); 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312541.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

提升Azure App Service的几个建议

本文介绍了6个技巧&#xff0c;这些技巧可以改善Azure App Service托管应用程序的性能。其中一些技巧是你现在就可以进行的配置变更&#xff0c;而其他技巧则可能需要对应用程序进行一些重新设计和重构&#xff0c; 本文的几个技巧对于常规企业部署依旧有指引作用。长话短说开发…

单向链表的逆转(数据结构)(c语言)

逆转单向链表的意思是&#xff1a;给定你一个单向链表&#xff0c;一个整数n&#xff08;n为要逆转的结点数&#xff09;&#xff0c;要求你把链表从头结点到第n个结点给逆转过来 图示&#xff1a; 给出一个单向链表&#xff0c;一个整数n4。也就是要求把该链表从头结点&#x…

广东职业教育信息化研究会2019年会暨区块链专题研讨会

兹定于2019年12月28日&#xff08;星期六&#xff09;上午9:30召开广东职业教育信息化研究会2019年会暨专题研讨会&#xff0c;本次会议由广东职业教育信息化研究会主办&#xff0c;华南师范大学网络教育学院协办。会议地址&#xff1a;广州市天河区中山大道西55号华南师范大学…

Serial.println()和Serial.print() (Arduino编程)

Arduino的输出基本就用到两个函数&#xff1a;print和println 区别是后者比前者多了回车换行 Serial.println(data)从串行端口输出数据&#xff0c;跟随一个回车&#xff08;ASCII 13或’r’&#xff09;和一个换行符&#xff08;ASCII 10或’n’&#xff09;&#xff0c;这个…

如何快速融入一个团队?

作者&#xff1a;邹溪源&#xff0c;长沙资深互联网从业者&#xff0c;架构师社区特邀嘉宾&#xff01;一我们难免需要离开一个圈子&#xff0c;加入一个陌生的集体。毋庸置疑&#xff0c;离开熟知的圈子&#xff0c;走向未知的圈子难免会产生许多畏惧甚至情怯&#xff0c;这都…

使用Arduino开发ESP32:wifi基本功能使用

1.建立网络&#xff08;AP&#xff09; 2.连接网络&#xff08;STA&#xff09; 3.扫描网络 1.建立网络&#xff08;AP&#xff09; 只需两步&#xff1a;1.引用WiFi库include<WiFi.h> 2.启动AP网络WiFi.softAP(ssid) 将下面代码上传到模块中&#xff1a; #include &l…

关于C#异步编程你应该了解的几点建议

前段时间写了一篇关于C#异步编程入门的文章&#xff0c;你可以点击《C#异步编程入门看这篇就够了》查看。这篇文章我们来讨论下关于C#异步编程几个不成文的建议&#xff0c;希望对你写出高性能的异步编程代码有所帮助。注&#xff1a;本文的很多内容都是学习《Effective C#》的…

数据库分区

一、分区原理分区并不是生成新的数据表&#xff0c;而是将表的数据均衡分摊到不同的硬盘&#xff0c;系统或是不同服务器存储介子中&#xff0c;实际上还是一张表。要实现这一功能&#xff0c;首先要了解数据库对水平分区表进行分区存储的原理。数据库分区和分表相似&#xff0…

(Arduino编程)Serial(串行通信)函数

串行端口用于Arduino和个人电脑或其他设备进行通信。所有Arduino控制器都有至少一个串行端口&#xff08;也称为UART或者USART&#xff09;。个人电脑可以通过USB端口与Arduino的引脚0(RX)和引脚1(TX) 进行通信。所以当Arduino的引脚0和引脚1用于串行通信功能时&#xff0c;Ard…

Arduino_esp32_WiFi代码

#include<WiFi.h>const char* ssid"BlackWalnut"; const char* password"blackwalnut";void setup() {Serial.begin(115200);while(WiFi.status()!WL_CONNECTED){delay(2500);WiFi.begin(ssid,password);Serial.println("正在连接...");}S…

如何在 C# 平台调用云开发?

▌关于作者苏震巍&#xff0c;云开发Linker计划成员&#xff0c;《微信开发深度解析》作者、Senparc.Weixin 微信 SDK 作者、微软最有价值专家&#xff08;MVP&#xff09;、盛派网络创始人兼首席架构师、微软 Ignite 技术大会讲师、从事软件及互联网研发已有26年&#xff0c;发…

如何打造组织级敏捷,你想知道的都在这里!

“敏捷是适应和响应变化的能力……敏捷组织将变化视为机遇&#xff0c;而不是威胁。” — Jim Highsmith注&#xff1a;Highsmith 在软件开发和 IT 行业有着超过 30 年的经验&#xff0c;曾是敏捷宣言的签署人之一&#xff0c;敏捷联盟的发起人和第一任理事&#xff0c;在很多行…

Azure DevOps Server CI - 自搭跨平台容器代理Agents

前言最近在地端(On-premises)幫團隊搭一套CI/CD流程&#xff0c;也順帶整理了一下從無到有的搭建過程&#xff0c;這次使用了docker技術來解決現有團隊使用CI/CD時讓現有CI/CD hosting環境過於複雜的問題。在開始之前&#xff0c;我先預備一下搭建的環境&#xff0c;如下:Windo…

python练习题:列表排序

Description 已知一个列表a [1,3,5,7,9]&#xff0c;系统会通过input()函数给你输入2、4、6、8中的任意一个数字&#xff0c;请你将这个数字和列表a中的数字重新排列&#xff0c;要求新列表中的数字依旧按从小到大的方式排列&#xff0c;您只需要输出新列表即可。 Input 系统会…

.Net Core 认证组件源码解析

不知不觉.Net Core已经推出到3.1了,大多数以.Net为技术栈的公司也开始逐步的切换到了Core,从业也快3年多了,一直坚持着.不管环境怎么变,坚持自己的当初的选择,坚持信仰 .Net Core是个非常优秀的框架,如果各位是从WebForm开始,一步步走到今天,自然而然就会发现.微软慢慢的开始将…

7-10 逆波兰表达式求值 (20 分)(c语言)(数据结构)

逆波兰表示法是一种将运算符&#xff08;operator&#xff09;写在操作数&#xff08;operand&#xff09;后面的描述程序&#xff08;算式&#xff09;的方法。举个例子&#xff0c;我们平常用中缀表示法描述的算式&#xff08;1 2&#xff09;*&#xff08;5 4&#xff09;…

在.NET Core下的机器学习--学习笔记

摘要.NET Core 在机器学习的应用场景&#xff0c;除了 ML .NET 还会介绍一个非常棒的開源技術 TensorFlow .NET &#xff0c; Keras .NET.讲师介绍本课内容人工智能介绍ML .NETICSharpCoreTensorFlow .NETKeras .NETSciSharp人工智能应用图像识别/物体识别自然语言/翻译搜索/知…

6-5 顺序表操作集 (20 分)(创建,查找,插入,删除)以及顺序表的理解

顺序表&#xff1a; 线性表的顺序存储 线性表的顺序存储是指在内存中用地址连续的一块存储空间顺序存放线性表的各元素 在程序设计语言中&#xff0c;一维数组在内存中占用的存储空间就是一组连续的存储区域&#xff0c;因此&#xff0c;用一维数组来表示顺序存储的数据区域是…

asp.net core 自定义基于 HttpContext 的 Serilog Enricher

asp.net core 自定义基于 HttpContext 的 Serilog EnricherIntro通过 HttpContext 我们可以拿到很多有用的信息&#xff0c;比如 Path/QueryString/RequestHeader 等请求信息, StatusCode/ResponseHeader 等响应信息&#xff0c;借助 HttpContext 我们可以在日志中记录很多有用…

我的 .NET Core 博客性能优化经验总结

点击上方蓝字关注“汪宇杰博客”导语去年8月&#xff0c;我用 .NET Core 重写了我的博客系统。经过一年多的优化&#xff0c;服务器响应速度从上线时候的 80ms 提高到了现在的 8ms&#xff0c;十倍提速。可惜由于部署在国外&#xff0c;自然不可抗力会导致中国用户晚上访问速度…