【转】基础知识系列2--线性表之链表
原文地址:http://www.cnblogs.com/mcgrady/p/3209419.html
上一篇我们总结完了顺序表,这一篇我们要总结的是线性表的链表,我想从以下几点进行总结。
1,为什么要使用链表?
2,链表的存储结构?
3,链表的常用操作代码实现?
1.为什么要使用链表
通过上一篇的学习,我们知道顺序表存在一些问题,主要有以下两个方面。
1,顺序表的长度是固定的,如果超出分配的长度就会造成溢出,如果存放的数据太少则会造成空间浪费。
2,在插入元素和删除元素时(尤其不在尾部时),会移动大量的元素,造成性能和效率低下。
基于以上问题,使用链表可以很好地避免顺序表中出现的问题。这也是我们要使用链表的原因。
2.链表的存储结构
从上图可以看出,单链表中的每个结点都包含一个“数据域”和一个“指针域”。“数据域”中包含当前结点的数据,“指针域”包含下一节点的存储地址,头指针head是指向开始结点的,结束结点没有后继结点,所以结束结点的指针域为空,即null。
3.链表的常用操作及实现代码
链表常用的操作有:
1,插入结点到表头
思路:将head头指针的next指针给新增结点的next,然后将整个新增结点给head头指针的next。因此时间复杂度为O(1)。
示意图:
2,插入结点到表尾
思路:插入方法与插入到表头一样,只不过多一个步骤就是通过head头指针循环找到终端结点。因此时间复杂度为O(n)。
示意图:
3,插入结点(1≤i≤ListLength(L))
思路:插入方法与插入到表头一样,多循环查找当前结点的动作。因此时间复杂度为O(n)。
示意图:
4,删除结点
思路:同插入结点一样,时间复杂度为O(n)。
示意图:
5,查找结点
思路:与插入结点和删除结点方法类似,时间复杂度为O(n)。
6,获取链表长度
思路:不像顺序表是连续存储的,获取表的长度非常容易。在链表中,数据不是连续存储的,因此需要循环遍历才能求得链表的长度,所以时间复杂度为O(n)。
代码实现:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define OK 0 5 #define ERROR -1 6 7 typedef int Status; //函数结果状态 8 typedef int ElemType; 9 typedef struct Node 10 { 11 ElemType data; 12 struct Node *next; 13 }Node; 14 typedef struct Node *ChainList; 15 Node *p; 16 ChainList head; 17 18 Status Init(ChainList *head) 19 { 20 *head = (ChainList)malloc(sizeof(Node)); 21 22 if(*head == NULL) 23 return ERROR; 24 25 (*head)->next = NULL; 26 27 return OK; 28 } 29 //由于第i个结点的存储地址是存储在第i-1个结点的next中,因此,先让指针指向第i-1个结点,然后生成一个新结点插入 30 Status Insert(ChainList head,int i,ElemType e) 31 { 32 int j=0; 33 ChainList p,s; 34 35 p = head; 36 while(p!=NULL&&j<i-1) //head内不保存数据 37 { 38 p = p->next; 39 j++; 40 } 41 42 if(p==NULL||j>i-1) //这个j>i-1代表着i不能输入小于1的非法值 43 return ERROR; 44 45 s = (ChainList)malloc(sizeof(Node)); 46 s->data = e; 47 s->next = p->next; 48 p->next = s; 49 50 return OK; 51 } 52 53 Status Delete(ChainList head,int i) 54 { 55 int j=0; 56 ElemType e; 57 ChainList p,s; 58 p=head; 59 60 while(p!=NULL&&j<i-1) 61 { 62 p = p->next; 63 j++; 64 } 65 66 if(p==NULL) 67 return ERROR; 68 else 69 { 70 s=p->next; 71 p->next = s->next; 72 e = s->data; 73 free(s); 74 return OK; 75 } 76 } 77 78 int GetLength(ChainList head) 79 { 80 int i=0; 81 ChainList p = head->next; 82 83 while(p!=NULL) 84 { 85 p = p->next; 86 i++; 87 } 88 89 return i; 90 } 91 92 Status GetDataByIndex(ChainList head,int i,ElemType *e) 93 { 94 int j=0; 95 ChainList p,s; 96 97 p=head->next; 98 99 while(p!=NULL&&j<i-1) 100 { 101 p=p->next; 102 j++; 103 } 104 105 if(p==NULL||j>i-1) 106 return ERROR; 107 *e = p->data; 108 109 return OK; 110 } 111 112 Status Display(ChainList head) 113 { 114 ChainList p=head->next; 115 printf("链表:"); 116 while(p!=NULL) 117 { 118 printf("%d ",p->data); 119 p=p->next; 120 } 121 printf("\n"); 122 123 return OK; 124 } 125 126 int main(void) 127 { 128 ChainList head; 129 ElemType e; 130 int j,k; 131 132 printf("初始化\n"); 133 if(Init(&head) == -1) 134 printf("Init Error\n"); 135 printf("初始化后,链表长度:%d\n",GetLength(head)); 136 137 printf("插入10条数据\n"); 138 srand((unsigned)time(NULL)); 139 for(j=0;j<10;j++) 140 { 141 if(Insert(head,1,j) == -1) 142 printf("Insert Error\n"); 143 } 144 Display(head); 145 146 printf("删除第3条数据\n"); 147 if(Delete(head,3) == -1) 148 printf("Delete Error\n"); 149 printf("删除成功\n"); 150 Display(head); 151 152 printf("获取第5个结点的数据\n"); 153 if(GetDataByIndex(head,5,&e) == -1) 154 printf("GetData Error\n"); 155 printf("%d\n",e); 156 157 return 0; 158 }
运行结果
转载于:https://www.cnblogs.com/losing-1216/p/4962527.html
【转】基础知识系列2--线性表之链表相关推荐
- Algorithms_基础数据结构(04)_线性表之链表_单向循环链表约瑟夫环问题
文章目录 大纲图 链表的经典面试题目 如何设计一个LRU缓存淘汰算法 约瑟夫问题 结构 分析 大纲图 链表的经典面试题目 如何设计一个LRU缓存淘汰算法 tip:单向链表 约瑟夫问题 N个人围成一圈, ...
- Algorithms_基础数据结构(02)_线性表之链表_单向链表
文章目录 大纲图 链表的经典面试题目 如何设计一个LRU缓存淘汰算法 约瑟夫问题 顺序表VS 链表 链表的定义 链表的特点 常见的链表结 单向链表 单向链表的查找 单向链表的插入 头插 尾部插入 中间 ...
- Algorithms_基础数据结构(03)_线性表之链表_双向链表
文章目录 大纲图 双向链表 双向链表的基本结构 双向链表的基本操作 头插 尾插 中间部位插入 删除头部 删除尾部 删除中间位置的数据 查找 更新 Code 总结 大纲图 双向链表 Algorithms ...
- c# getresponsestream返回byte[]_C# 基础知识系列-13 常见类库(三)
0. 前言 在<C# 基础知识系列- 13 常见类库(二)>中,我们介绍了一下DateTime和TimeSpan这两个结构体的内容,也就是C#中日期时间的简单操作.本篇将介绍Guid和Nu ...
- [WPF 基础知识系列] —— 绑定中的数据校验Vaildation
[WPF 基础知识系列] -- 绑定中的数据校验Vaildation 原文:[WPF 基础知识系列] -- 绑定中的数据校验Vaildation 前言: 只要是有表单存在,那么就有可能有对数据的校验需 ...
- 有十五个数按由大到小顺序存放在一个数组中_数据结构基础 (代码效率优化, 线性表, 栈, 队列, 数组,字符串,树和二叉树,哈希表)...
作者:张人大 代码效率优化 复杂度 -- 一个关于输入数据量n的函数 时间复杂度 -- 昂贵 与代码的结构设计有着紧密关系 一个顺序结构的代码,时间复杂度是O(1), 即任务与算例个数 n 无关 空间 ...
- 图像处理基础知识系列之五:贝叶斯方法简单梳理
图像处理基础知识系列之五:贝叶斯方法简单梳理 文章来源: 刘未鹏 数学之美番外篇:平凡而又神奇的贝叶斯方法(作者是个技术兼心理学 ...
- [C#基础知识系列]专题十七:深入理解动态类型
本专题概要: 动态类型介绍 为什么需要动态类型 动态类型的使用 动态类型背后的故事 动态类型的约束 实现动态行为 总结 引言: 终于迎来了我们C# 4中特性了,C# 4主要有两方面的改善--Com 互 ...
- c# string 占位符_C# 基础知识系列- 9 字符串的更多用法(一)
0. 前言 在前面的文章里简单介绍了一下字符串的相关内容,并没有涉及到更多的相关内容,这一篇将尝试讲解一下在实际开发工作中会遇到的字符串的很多操作. 1. 创建一个字符串 这部分介绍一下如何创建一个字 ...
最新文章
- 资深算法工程师万宫玺:Java工程师转型AI的秘密法宝——深度学习框架Deeplearning4j | 分享总结
- 一个四维的人在三维世界里到底长什么模样?
- 物联网现状及落地难点
- Java问题汇集(1)
- GitHub 上数十个 NetBeans 开源项目被卷入供应链攻击
- windows process activation service 通信_Android四大组件——Service篇
- ASP.NET MVC搭建项目后台UI框架—1、后台主框架
- hystrix熔断器之command实现
- Linux读取内核空间,linux,arm_arm如何在内核空间直接读写某个物理地址(或者进程的虚拟地址),linux,arm,c,linux-kernel,memory - phpStudy...
- 网络安全实验3 漏洞扫描
- 单点登录原理以及简单实现
- 让360双核浏览器默认极速模式打开网页
- mysql数据库修改初始密码
- Vuecli中添加elementui插件
- PHP+MySQL实现留言板功能(二)
- “裕同集团易普优APS项目启动大会”顺利召开
- 为Dynamics 365 USD设置打开调试面板的自定义快捷键
- mblock——火焰灯
- 什么是Redis缓存穿透?redis面试题及答案(附面试题大全)
- vm运行自己编译的linux,Virtualbox运行 自编译的Linux
热门文章
- 3d 根据弧长算角度_3D立体画,让你身临其境
- 2007-11-22 21:24 大端(Big Endian)与小端(Little Endian)详解
- Oracle,Mysql,Sqlserver数据库连接串(总爱忘,留着备用)
- 小辣椒p60手机怎么样_专坑手机小白的两大品牌,起售价3599,谁交了“智商税”...
- 邮件策略在域树中的实战应用:Exchange2003系列之十
- IOCP Thread Pool 在 C# 的Safe实现
- 电子计算机的基本结构基于存储程序思想是由,计算机应用基础第一章复习题
- JDK历史版本主要新特性
- 工作中 linux 常用命令:vi、cp、mv、rm、kill、curl、tail
- Spark解决的问题与体系结构