《C#从现象到本质》读书笔记(九)第11章C#的数据结构
《C#从现象到本质》读书笔记(九)第11章C#的数据结构
C#中的数据结构可以分为两类:非泛型数据结构和泛型数据结构。
通常迭代器接口需要实现的方法有:1)hasNext,是否还有下一个元素。2)Next,移动到下一个元素。3)Reset,重置。
C#中对迭代器模式的实现就是IEnumerable接口。
使用yield关键字实现方法GetEnumerator。yield的延迟执行特性体现在:只有当需要取值时,才会执行,否则状态机的状态就停在0。
foreach迭代时,不能直接更改集合成员的值,但可以对成员本身的字段和属性进行重新赋值。
IEnumerable的缺点如下:1)IEnumerable功能有限,不能插入和删除。2)访问IEnumerable只能通过迭代,不能使用索引器。迭代时非线程安全的。3)访问IEnumerable必定造成一次求值。
IEnumerable小结如下:
1)IEnumerable及其泛型版本是所有集合的基础,它赋予集合迭代的能力。
2)通常将迭代中拿出来的元素称为iterator。
3)实现IEnumerable接口,必须实现它唯一的方法GetEnumerator。
4)方法GetEnumerator返回一个IEnumerator类型的输出。
5)IEnumerator接口拥有一个Current属性,我们需要实现它的get方法,返回当前的iterator。
6)需要为IEnumerator类型增加一个int类型的值,记录当位置。该类型的初始值为-1。IEnumerator类型的Reset方法将这个值设为-1。
7)IEnumerator接口的MoveNext方法将位置增加1,并返回是否还有下一个元素。
8)通过yield简化方法GetEnumerator的实现。
9)在C#中使用foreach将会隐式地调用MoveNext方法。
10)IEnumerable<T>是整个LINQ的基础。整个LINQ都基于IEnumerable<T>的扩展方法。C#大部分数据结构都实现了IEnumerable<T>。
11)IEnumerable的派生类由于没有反省,所以基本不考虑使用。
常用数据结构特征以及操作时间复杂度见下表
数据结构 | 类型及备注 | 插入和删除 | 查找 |
Array |
顺序存储的线性表 定长 |
不支持(这里的插入与删除指会更改表长的行为) | O(N) |
LinkedList<T> |
链式储存的线性表 不定长 无法用下表访问 |
O(1) | O(N) |
List<T> |
顺序储存的线性表 不定长 动态扩容 |
O(N),结尾则是O(1) | O(N) |
Stack<T> |
栈 不定长 动态扩容 |
O(1) | 只能访问栈顶 |
Queue<T> |
队列 不定长 动态扩容 |
O(1) | 只能访问队头 |
Dictionary<K,T> |
保存键值对 使用开散列法 不定长 动态扩容 长度总为质数 |
O(1) | O(1) |
SortedList<K,T> |
保存键值对 内部使用数组实现 保持有序 不定长 |
O(log N) | O(log N) |
SortedDictionary<K,T> |
保存键值对 内部使用红黑树实现 保持有序 不定长 |
O(log N) | O(log N) |
HashSet<T> |
使用开散列法 不定长 动态扩容 长度总为质数 是不含值的字典,故复杂度和它完全相同 |
O(1) | O(1) |
SortedSet<T> |
内部使用红黑树实现 保持有序 不定长 是不含值的SortedDictionary<K,T>,故复杂度和它完全相同 |
O(log N) | O(log N) |
如何选择数据结构:
首先对于栈和队列,直接使用对应的数据结构即可。对于普通数据源:
如果数据源不是键值对:
a)数据量大,没有重复数据:使用HashSet<T>。
b)数据量大,但可能有重复数据;或数据量小:使用Array,List<T>或LinkedList<T>。
c)没有重复数据,且希望集合处于有序状态:使用SortedSet<T>。
d)有重复数据,且希望集合处于有序状态:没有现车的数据结构提供,可以考虑基于数组实现一个。
如果是键值对:首选是类型安全的字典,然后,如果希望集合处于有序状态,从SortedList<k,T>和SortedDictionary<K,T>中进行权衡。如果数据源数据很少,可以考虑List<KeyValuePair<K,T>>替代字典。
哈希(散列)表(Hashtable)是一种键值对类型的数据结构。它的特点是查找速度飞快。C#的HashTable类把a的最大值定为0.72(Java为0.75),当HashTable中的被占用空间达到72%的时候就将该HashTable自动扩容。
冲突解决技术可分为两大类:开散列法(又称为链地址法)和闭散列法(又称为开放地址法)。对于开散列法,发生冲突的元素存储于数组空间之外。Dictionary<K,T>使用的就是这种方式。对于闭散列法,发生冲突的元素存储于数组空间之内。HashTable使用的就是这种方式。
C#的HashTable内部借助了数组,并采用开放寻址加双重哈希。它通过一个结构体bucket来表示哈希表中的单个元素,这个结构体中有三个成员:a)key:表示键,即哈希表中的关键字。b)表示值,即跟关键字所对应的值。c)hash_coll:int类型,用于表示键所对应的哈希码。
ArrrayList是实现了基于动态数组的数据结构,存在不安全类型与装箱拆箱的缺点。
《C#从现象到本质》读书笔记(九)第11章C#的数据结构的更多相关文章
- C++ Primer 读书笔记:第11章 泛型算法
第11章 泛型算法 1.概述 泛型算法依赖于迭代器,而不是依赖容器,需要指定作用的区间,即[开始,结束),表示的区间,如上所示 此外还需要元素是可比的,如果元素本身是不可比的,那么可以自己定义比较函数 ...
- SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章)
SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章) 示例数据库:点我 CHAPTER 08 数据修改 8.1 插入数据 8.1.1 INSERT VALUES 语句 8.1 ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
- 《Android开发艺术探索》读书笔记 (3) 第3章 View的事件体系
本节和<Android群英传>中的第五章Scroll分析有关系,建议先阅读该章的总结 第3章 View的事件体系 3.1 View基本知识 (1)view的层次结构:ViewGroup也是 ...
- 《Linux内核设计与实现》读书笔记——第一、 二章
<Linux内核设计与实现>读书笔记--第一. 二章 标签(空格分隔): 20135321余佳源 第一章 Linux内核简介 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确 ...
- 《Android开发艺术探索》读书笔记 (9) 第9章 四大组件的工作过程
第9章 四大组件的工作过程 9.1 四大组件的运行状态 (1)四大组件中只有BroadcastReceiver既可以在AndroidManifest文件中注册,也可以在代码中注册,其他三个组件都必须在 ...
- MDX Step by Step 读书笔记(九) - Working with Time 处理时间
开篇介绍 这一章节主要用到的 MDX 函数: PeriodsToDate( [Level , [Member]] ) - 从指定级别的范围内,返回与指定成员同一级别,从第一个期间开始到指定成员结束的期 ...
- Machine Learning for hackers读书笔记(九)MDS:可视化地研究参议员相似性
library('foreign') library('ggplot2') data.dir <- file.path('G:\\dataguru\\ML_for_Hackers\\ML_for ...
- 深入理解linux网络技术内幕读书笔记(九)--中断与网络驱动程序
Table of Contents 1 接收到帧时通知驱动程序 1.1 轮询 1.2 中断 2 中断处理程序 3 抢占功能 4 下半部函数 4.1 内核2.4版本以后的下半部函数: 引入软IRQ 5 ...
随机推荐
- Flask--(项目准备)--添加日志
日志:记录程序运行的状态,在manage.py同级目录下创建logs文件夹 定义日志文件: import logging from logging.handlers import RotatingFi ...
- 算法实践--不相交集合(Disjoint Sets)
什么是不相交集合(Disjoint Sets) 是这样的一组set,任何元素最多只能在一个set中 至少支持查找Find和合并Union操作 实现方式(基于树) 每个set都是一棵树 每棵树都由树的根 ...
- TCP/IP学习20180630-数据链路层-router choose
IP路由选择 当一个IP数据包准备好了的时候,IP数据包(或者说是路由器)是如何将数据包送到目的地的呢?它是怎么选择一个合适的路径来"送货"的呢? 最特殊的情况是目的主机和主机直连 ...
- Make a plan, and stand for it!
我发现博主本人善于事前做计划,事后做总结.但是不善于坚持自己的计划.就拿10.1这个假期来讲,放假前看多许多的攻略,计划了很多条的自驾出行的路线,但是好像一条也没坚持,最后选择了一条临时的线路,而且临 ...
- WordPress版微信小程序2.1.5版发布
WordPress版微信小程序功能已经基本完善,利用这套程序,搭配WordPress提供的rest api,WordPress网站的站长可以快速搭建属于自己的网站微信小程序 . WordPress版微 ...
- 关于CoreData的用法
有些同事觉得CoreData是一个看不懂,理解不清的神秘东东,其实ios的本地数据储存是一个sqlite数据库,一个简易的数据库,而这个CoreData是否支持所有储存的数据呢,显然不是的,站在我的角 ...
- 回滚的意义---JDBC事务回滚探究
JDBC手动事务提交回滚的常见写法一直是rollback写在commit的catch之后: try{ conn.setAutoCommit(false); ps.executeUpdate(); ps ...
- 【学习】数据处理基础知识(基本功能)【pandas】
本章介绍pandas的重要功能,只记录一些重点内容 1.重新索引 pandas对象的一个重要方法是reindex,其作用是创建一个适应用新索引的新对象 #重新索引 obj = pd.Series([4 ...
- 第二篇*1、Python基本数据类型
数据类型: 变量可以处理不同类型的值,基本的类型是数和字符串.使用变量时只需要给它们赋一个值.不需要声明或定义数据类型.Python3 中有六个标准的数据类型:Number(数字),String(字符 ...
- 微信小程序--预览previewImage(长按保存图片)
最近开发小程序,想实现二维码图片长按保存,发现无法保存,只能让图片先预览,再保存.注意:只有太阳码才有长按保存和识别功能,普通二维码只有长按保存功能. <image class='banner' ...