博客
关于我
2.3.Stack Queue
阅读量:798 次
发布时间:2023-04-16

本文共 2566 字,大约阅读时间需要 8 分钟。

Stack 实现

Stack(栈)是一种先进后出(LIFO)的数据结构,常用于管理程序运行时的方法调用顺序。在 .NET 中,Stack 类位于 System.dll 文件中,实现的逻辑位于 mscorlib.dll 的第 330 行。由于我们只关注泛型栈,因此需要调试 System.dll 来分析其内部逻辑。

在调试符号中选择添加 System.dll 即可轻松进入调试模式,这对 VS 的用户来说无疑是大大的便利。通过这种方式,我们可以直接查看栈的内部实现,深入了解其工作原理,从而更好地优化代码开发流程。

Stack 内部

Stack 的内部实现主要依赖动态数组和一些控制变量。以下是实现细节:

1. `_size`:表示当前栈的大小,用于控制数组中指针的位置。

2. `_array`:存储实际数据的动态数组,类型由泛型 T 决定。

3. `_num`:原先用于扩容时的计算字段,现已被 `_size` 取代。

4. `_defaultCapacity`:默认扩容时的容量大小,通常为 4。

5. `_emptyArray`:一个静态空数组,用于初始化栈。

6. `_version`:用于检测数组结构发生变化的版本号。

Stack 构造函数

Stack 提供多个构造函数以满足不同使用场景:

1. `public Stack()`:默认构造函数,初始化时使用空数组 `_emptyArray`。

2. `public Stack(int capacity)`:指定初始容量,直接创建大小为 capacity 的数组。

3. `public Stack(IEnumerable

collection)`:通过集合初始化栈,适用于从集合中逐一添加元素的场景。

Push 操作(O(1) 时间复杂度)

Push 操作将一个项添加到栈顶部。实现细节如下:

1. 检查当前栈是否已满,如果已满则扩容。

2. 扩容时创建新数组,大小为当前数组大小的两倍(或默认容量 4),并将现有数据复制到新数组中。

3. 将新项添加到栈顶,更新 `_size`。

4. 更新 `_version`,用于区分不同版本的栈实例。

Pop 操作(O(1) 时间复杂度)

Pop 操作从栈顶部移除一个项。实现细节如下:

1. 检查栈是否为空,若为空抛出异常。

2. 更新 `_version`。

3. 从 `_size` 递减的位置取出项,并将该位置设置为默认值(即数组中对应位置的 T 类型的默认值)。

4. 返回被移除的项。

Peek 操作(O(1) 时间复杂度)

Peek 操作允许开发者查看栈顶部的项而不移除它。实现细节如下:

1. 检查栈是否为空,若为空抛出异常。

2. 直接访问 `_array[_size - 1]`,返回栈顶部的项。

Contains 操作(O(n) 时间复杂度)

Contains 操作用于检查栈中是否存在指定的项。实现细节如下:

1. 遍历从 `_head` 到 `_tail` 的所有项(从栈底部到栈顶部)。

2. 使用 `EqualityComparer.Default` 比较项是否存在。

3. 如果找到匹配项返回 `true`,否则返回 `false`。

Queue 实现

Queue(队列)是一种先进先出(FIFO)的数据结构,在 .NET 中由 Queue 类实现,内部实现位于 mscorlib.dll 的第 471 行。与 Stack 不同,Queue 使用两个指针(_head 和 _tail)来管理数据的插入和移除操作。

Queue 的内部实现主要依赖以下字段:

1. `_array`:存储数据的动态数组。

2. `_head`:指针,指向队列的当前头部项的位置。

3. `_tail`:指针,指向队列的当前尾部项的位置。

4. `_size`:表示队列中当前有多少项。

5. `_DefaultCapacity`:默认扩容时的容量大小,通常为 4。

6. `_emptyArray`:静态空数组,用于初始化队列。

Queue 构造函数

Queue 提供多个构造函数:

1. `public Queue()`:默认构造函数,初始化时使用空数组 `_emptyArray`。

2. `public Queue(int capacity)`:指定初始容量,创建大小为 capacity 的数组。

3. `public Queue(IEnumerable

collection)`:通过集合初始化队列,逐一添加集合中的项。

Enqueue 操作(O(1) 时间复杂度)

Enqueue 操作将一个项添加到队列末尾。实现细节如下:

1. 检查是否有空间,如果没有空间调用 `SetCapacity` 方法扩容。

2. 更新 `_tail` 指针到下一个位置。

3. 更新 `_size`。

4. 更新 `_version`。

Dequeue 操作(O(1) 时间复杂度)

Dequeue 操作从队列头部移除一个项。实现细节如下:

1. 检查是否为空,若为空抛出异常。

2. 将 `_head` 指针移动到下一个位置,并将该位置的项设置为 null。

3. 更新 `_size` 和 `_version`。

4. 返回被移除的项。

Peek 操作(O(1) 时间复杂度)

Peek 操作允许开发者查看队列头部的项而不移除它。实现细节如下:

1. 检查是否为空,若为空抛出异常。

2. 返回 `_array[_size]` 中的项。

Contains 操作(O(n) 时间复杂度)

Contains 操作用于检查队列中是否存在指定的项。实现细节如下:

1. 从 `_head` 到 `_tail` 遍历所有项。

2. 使用 `EqualityComparer.Default` 比较项是否存在。

3. 返回 `true` 或 `false`。

Enumerator

Queue 提供一个枚举器,允许开发者遍历队列中的所有项。默认枚举器通过循环 `_array` 并从 `_head` 到 `_tail` 检查每个位置是否不为空来获取项。

通过调用 `GetEnumerator()` 方法可以获取枚举器实例。

转载地址:http://lcgfk.baihongyu.com/

你可能感兴趣的文章
MySQL中interactive_timeout和wait_timeout的区别
查看>>
mysql中int、bigint、smallint 和 tinyint的区别、char和varchar的区别详细介绍
查看>>
mysql中json_extract的使用方法
查看>>
mysql中json_extract的使用方法
查看>>
mysql中kill掉所有锁表的进程
查看>>
mysql中like % %模糊查询
查看>>
MySql中mvcc学习记录
查看>>
mysql中null和空字符串的区别与问题!
查看>>
MySQL中ON DUPLICATE KEY UPDATE的介绍与使用、批量更新、存在即更新不存在则插入
查看>>
MYSQL中TINYINT的取值范围
查看>>
MySQL中UPDATE语句的神奇技巧,让你操作数据库如虎添翼!
查看>>
Mysql中varchar类型数字排序不对踩坑记录
查看>>
MySQL中一条SQL语句到底是如何执行的呢?
查看>>
MySQL中你必须知道的10件事,1.5万字!
查看>>
MySQL中使用IN()查询到底走不走索引?
查看>>
Mysql中使用存储过程插入decimal和时间数据递增的模拟数据
查看>>
MySql中关于geometry类型的数据_空的时候如何插入处理_需用null_空字符串插入会报错_Cannot get geometry object from dat---MySql工作笔记003
查看>>
mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
查看>>
mysql中出现Unit mysql.service could not be found 的解决方法
查看>>
mysql中出现update-alternatives: 错误: 候选项路径 /etc/mysql/mysql.cnf 不存在 dpkg: 处理软件包 mysql-server-8.0的解决方法(全)
查看>>