Stack(栈)是一种后进先出的数据结构,其中最核心的两个方法分别为Push(入栈)和Pop(出栈)两个操作,那么.NET类库是如何实现这种数据结构呢?为了降低学习成本,这里将根据.NET源码的实现,结合其中的核心设计思想,得出一个简化版本的实现:
1 | using System; |
必须明确的一点是Stack
接下来来看一下Push(T item)函数的实现。这里的第一步操作其实就是执行一次判断,判断当前_array数组的元素个数是否已经满了,假如满了的话,就要对数组进行扩充。.NET源码对于数组扩充的设计还是比较巧妙的,当_array为空的时候,默认开始分配的数组个数为4,既new T[4],假如要插入的是第5个元素的时候,这时数组的个数不足,就声明一个新的T[] array,并将个数扩充为_array个数的2倍,之后再将_array元素一个个复制到新的array中,最后将_array字段指向array,就完成了数组扩充的工作。这一步在前面的代码中的实现应该是很清晰的,不过需要注意的一点是这里的Copy(_array,array)函数是我自己的一个简单的实现,跟.NET源码中的实现是很不一样的,.NET源码是调用一个Array.Copy(this._array, 0, array, 0, this._size)的函数,它的底层应该是用C++实现了数组复制的更好的优化。通过一张图来看一下数组扩容的过程:
最后来看一下Pop()函数的实现。首先先判断当前数组的个数是否大于0,小于等于0的话就会抛出异常。之后就将_size-=1,得到要Pop的对象在数组的位置。取出_array[_size]后,就调用default(T)填充_array[_size]的位置,这样做的一个好处是取消对原来的对象的引用,是其能够成为垃圾回收的对象,更好地减少内存的占用。总体而言Pop()实现还是比较简单的。
从前面我们知道,使用Stack