ArrayList,List等非链式线性结构是如何实现动态增长的
2014-02-19 02:39
323 查看
以前一直很好奇ArrayList和List等结构是怎么实现动态增长的。由于以前基础不扎实一直没深究,直接实现IList接口的时候也是写的一个很大长度的数组,最近在实现数据结构的时候也遇到了这个问题,带着这个问题,研究了.net框架的源码终于给解决了.很开心
ArrayList的内部数组是这个
如图
很显然这个数组是在构造函数分配的空间点进构造函数如图
点进emptyArray如图
看到发现他是个静态的变量可以联想到是在静态构造函数中分配空间的果然在类中发现了静态构造函数我们点进去如图
这里就证明了我以前的结论是错的,.net源码里并没有为数组初始分配一个很大的空间。而分配一个很大的空间类似int []nums = new int[10000]的缺点很明显浪费空间。这里就不细说了 那.net框架是如果做到动态添加元素的呢?我们点进ArrayList的Add方法如图
这里我解释下这个size就是数组的最大长度也就是说当数组的长度 等于这个最大长度的就进入if语句逻辑 这里就开始重新给数组分配空间了它具体如何做到的呢 点进EnsureCapacity方法如图
可能有的人开到16进制就看不下去。研究源码就应该穷追猛打,吾辈之程序猿又怎能被微软的一点手段放弃.咋一看这段代码的确没什么特别, 这里个人认为了微软用了观察者设计模式的思想 。首先intnum
= (this._items.Length
== 0) ? 4 : (this._items.Length
* 2); num 如果item的长度是0 就赋值为4也就是初值,如果不是0就翻倍. num就是数组的动态长度,也就是说数组的长度是由2,变到4变到8变到16 而把0x7fefffff数转化一下 我们会发现这个数的值是2146435071 soga.这正好是int类似的上限也就是说动态增长是不能封顶的! 但是到底在哪里改变的数组呢?我们点开Capacity如图
给Capacity赋值调用set方法value就是刚刚的num也就是数组的动态长度.net框架这里new了一个新的destinationArray长度是新长度 然后调用Array.Copy拷贝数组完成赋值。实现了动态增长。
哈哈是不是很神奇?
分析:
这种设计非常科学优点有二:
1.动态增长避免了空间的浪费
2.最大长度每次乘以2 不会有太多次动态增长的情况。毕竟每次增长要调用Array.Copy方法有个O(n)的时间复杂度
ArrayList的内部数组是这个
如图
很显然这个数组是在构造函数分配的空间点进构造函数如图
点进emptyArray如图
看到发现他是个静态的变量可以联想到是在静态构造函数中分配空间的果然在类中发现了静态构造函数我们点进去如图
这里就证明了我以前的结论是错的,.net源码里并没有为数组初始分配一个很大的空间。而分配一个很大的空间类似int []nums = new int[10000]的缺点很明显浪费空间。这里就不细说了 那.net框架是如果做到动态添加元素的呢?我们点进ArrayList的Add方法如图
这里我解释下这个size就是数组的最大长度也就是说当数组的长度 等于这个最大长度的就进入if语句逻辑 这里就开始重新给数组分配空间了它具体如何做到的呢 点进EnsureCapacity方法如图
可能有的人开到16进制就看不下去。研究源码就应该穷追猛打,吾辈之程序猿又怎能被微软的一点手段放弃.咋一看这段代码的确没什么特别, 这里个人认为了微软用了观察者设计模式的思想 。首先intnum
= (this._items.Length
== 0) ? 4 : (this._items.Length
* 2); num 如果item的长度是0 就赋值为4也就是初值,如果不是0就翻倍. num就是数组的动态长度,也就是说数组的长度是由2,变到4变到8变到16 而把0x7fefffff数转化一下 我们会发现这个数的值是2146435071 soga.这正好是int类似的上限也就是说动态增长是不能封顶的! 但是到底在哪里改变的数组呢?我们点开Capacity如图
给Capacity赋值调用set方法value就是刚刚的num也就是数组的动态长度.net框架这里new了一个新的destinationArray长度是新长度 然后调用Array.Copy拷贝数组完成赋值。实现了动态增长。
哈哈是不是很神奇?
分析:
这种设计非常科学优点有二:
1.动态增长避免了空间的浪费
2.最大长度每次乘以2 不会有太多次动态增长的情况。毕竟每次增长要调用Array.Copy方法有个O(n)的时间复杂度
相关文章推荐
- 线性表的链式存储结构之单链表类的实现之补充_Java
- 数据结构之线性表――链式存储结构之单链表(php代码实现)
- 栈的线性储存结构与链式储存结构的实现(C语言)。
- 链式结构实现线性表的基本操作
- 链式结构线性表的实现(二)
- PAT 02-线性结构3 Reversing Linked List 【JAVA实现】
- 动态栈 栈结构的链式实现
- 线性表的顺序储存结构定义(动态)实现
- (二)线性结构之LinkedList的实现
- (一)线性结构之ArrayList的实现
- 迎接2012之集合和泛型(2)------线性表的链式结构基本实现
- 线性表的链式存储结构之单链表结点类的实现_Java
- 数据结构之线性表代码实现顺序存储,链式存储,静态链表(选自大话数据结构)
- 2.4_线性表的链式存储结构_单链表具体实现
- 线性结构的顺序存储和链式存储的实现代码(一)
- 数据结构2----线性表顺序存储和链式存储的实现(霜之小刀)
- 数据结构 | 如何实现线性表的顺序结构
- ArrayList、LinkedList和HashSet、TreeSet以及HashMap、TreeMap是如何实现存储的?
- C++数据结构之List--线性实现
- 数据结构算法代码实现——线性表的链式表示与实现(单链表)(三 )