C#:数据结构queue队列源码:循环使用数组头标,尾标,防止不停扩容数组
https://referencesource.microsoft.com/#mscorlib/system/collections/queue.cs
概述
- 初始化:默认32个,每次2倍扩。所以在初始化时,能预设大小,防止频繁扩容
public Queue()
: this(32, (float)2.0)
- 入队扩容:内部是个数组,发现size不够,扩容。当头索引在尾索引前,复制size大小到新newarray里;当尾索引在头前,先复制头到数组size-1标,再复制数组0标到尾
private void SetCapacity(int capacity){Object[] newarray = new Object[capacity];if (_size > 0){//如果头在前面if (_head < _tail){Array.Copy(_array, _head, newarray, 0, _size);}//尾在前,头在后,中间是nullelse{//先复制头到数组size-1标Array.Copy(_array, _head, newarray, 0, _array.Length - _head);//再复制数组0标到尾Array.Copy(_array, 0, newarray, _array.Length - _head, _tail);}}_array = newarray;_head = 0;_tail = (_size == capacity) ? 0 : _size; //_size 是指原_array不为空元素的数量_version++;}
- 入队:容量够,放在数组_tail标处,同时 _tail = (_tail + 1) % _array.Length,可能导致_head > _tail,后面如需扩容时分两步,先先复制头到数组size-1标,再复制数组0标到尾;容量不够,先扩容
// Adds obj to the tail of the queue.//public virtual void Enqueue(Object obj){if (_size == _array.Length){int newcapacity = (int)((long)_array.Length * (long)_growFactor / 100);if (newcapacity < _array.Length + _MinimumGrow){newcapacity = _array.Length + _MinimumGrow;}SetCapacity(newcapacity);}_array[_tail] = obj;_tail = (_tail + 1) % _array.Length;_size++;_version++;}
- 出队:头标_head复制给新Object,_array[_head] = null;(清除内存),再_head = (_head + 1) % _array.Length;
public virtual Object Dequeue(){if (Count == 0)throw new InvalidOperationException(("InvalidOperation_EmptyQueue"));Contract.EndContractBlock();Object removed = _array[_head];_array[_head] = null;_head = (_head + 1) % _array.Length;_size--;_version++;return removed;}
C#队列全部源码
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*=============================================================================
**
** Class: Queue
**
** <OWNER>Microsoft</OWNER>
**
** Purpose: A circular-array implementation of a queue.
**
**
=============================================================================*/
namespace System.Collections {using System;using System.Security.Permissions;using System.Diagnostics;using System.Diagnostics.CodeAnalysis;using System.Diagnostics.Contracts;// A simple Queue of objects. Internally it is implemented as a circular// buffer, so Enqueue can be O(n). Dequeue is O(1).[DebuggerTypeProxy(typeof(System.Collections.Queue.QueueDebugView))] [DebuggerDisplay("Count = {Count}")]
[System.Runtime.InteropServices.ComVisible(true)][Serializable]public class Queue : ICollection, ICloneable {private Object[] _array;private int _head; // First valid element in the queueprivate int _tail; // Last valid element in the queueprivate int _size; // Number of elements.private int _growFactor; // 100 == 1.0, 130 == 1.3, 200 == 2.0private int _version;[NonSerialized]private Object _syncRoot;private const int _MinimumGrow = 4;private const int _ShrinkThreshold = 32;// Creates a queue with room for capacity objects. The default initial// capacity and grow factor are used.public Queue() : this(32, (float)2.0) {}// Creates a queue with room for capacity objects. The default grow factor// is used.//public Queue(int capacity) : this(capacity, (float)2.0) {}// Creates a queue with room for capacity objects. When full, the new// capacity is set to the old capacity * growFactor.//public Queue(int capacity, float growFactor) {if (capacity < 0)throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));if (!(growFactor >= 1.0 && growFactor <= 10.0))throw new ArgumentOutOfRangeException("growFactor", Environment.GetResourceString("ArgumentOutOfRange_QueueGrowFactor", 1, 10));Contract.EndContractBlock();_array = new Object[capacity];_head = 0;_tail = 0;_size = 0;_growFactor = (int)(growFactor * 100);}// Fills a Queue with the elements of an ICollection. Uses the enumerator// to get each of the elements.//public Queue(ICollection col) : this((col==null ? 32 : col.Count)){if (col==null)throw new ArgumentNullException("col");Contract.EndContractBlock();IEnumerator en = col.GetEnumerator();while(en.MoveNext())Enqueue(en.Current);}public virtual int Count {get { return _size; }}public virtual Object Clone() {Queue q = new Queue(_size);q._size = _size;int numToCopy = _size;int firstPart = (_array.Length - _head < numToCopy) ? _array.Length - _head : numToCopy;Array.Copy(_array, _head, q._array, 0, firstPart);numToCopy -= firstPart;if (numToCopy > 0)Array.Copy(_array, 0, q._array, _array.Length - _head, numToCopy);q._version = _version;return q;}public virtual bool IsSynchronized {get { return false; }}public virtual Object SyncRoot {get { if( _syncRoot == null) {System.Threading.Interlocked.CompareExchange(ref _syncRoot, new Object(), null); }return _syncRoot; }}// Removes all Objects from the queue.public virtual void Clear() {if (_head < _tail)Array.Clear(_array, _head, _size);else {Array.Clear(_array, _head, _array.Length - _head);Array.Clear(_array, 0, _tail);}_head = 0;_tail = 0;_size = 0;_version++;}// CopyTo copies a collection into an Array, starting at a particular// index into the array.// public virtual void CopyTo(Array array, int index){if (array==null)throw new ArgumentNullException("array");if (array.Rank != 1)throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));if (index < 0)throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));Contract.EndContractBlock();int arrayLen = array.Length;if (arrayLen - index < _size)throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));int numToCopy = _size;if (numToCopy == 0)return;int firstPart = (_array.Length - _head < numToCopy) ? _array.Length - _head : numToCopy;Array.Copy(_array, _head, array, index, firstPart);numToCopy -= firstPart;if (numToCopy > 0)Array.Copy(_array, 0, array, index+_array.Length - _head, numToCopy);}// Adds obj to the tail of the queue.//public virtual void Enqueue(Object obj) {if (_size == _array.Length) {int newcapacity = (int)((long)_array.Length * (long)_growFactor / 100);if (newcapacity < _array.Length + _MinimumGrow) {newcapacity = _array.Length + _MinimumGrow;}SetCapacity(newcapacity);}_array[_tail] = obj;_tail = (_tail + 1) % _array.Length;_size++;_version++;}// GetEnumerator returns an IEnumerator over this Queue. This// Enumerator will support removing.// public virtual IEnumerator GetEnumerator(){return new QueueEnumerator(this);}// Removes the object at the head of the queue and returns it. If the queue// is empty, this method simply returns null.public virtual Object Dequeue() {if (Count == 0)throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EmptyQueue"));Contract.EndContractBlock();Object removed = _array[_head];_array[_head] = null;_head = (_head + 1) % _array.Length;_size--;_version++;return removed;}// Returns the object at the head of the queue. The object remains in the// queue. If the queue is empty, this method throws an // InvalidOperationException.public virtual Object Peek() {if (Count == 0)throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EmptyQueue"));Contract.EndContractBlock();return _array[_head];}// Returns a synchronized Queue. Returns a synchronized wrapper// class around the queue - the caller must not use references to the// original queue.// [HostProtection(Synchronization=true)]public static Queue Synchronized(Queue queue){if (queue==null)throw new ArgumentNullException("queue");Contract.EndContractBlock();return new SynchronizedQueue(queue);}// Returns true if the queue contains at least one object equal to obj.// Equality is determined using obj.Equals().//// Exceptions: ArgumentNullException if obj == null.public virtual bool Contains(Object obj) {int index = _head;int count = _size;while (count-- > 0) {if (obj == null) {if (_array[index] == null)return true;} else if (_array[index] != null && _array[index].Equals(obj)) {return true;}index = (index + 1) % _array.Length;}return false;}internal Object GetElement(int i){return _array[(_head + i) % _array.Length];}// Iterates over the objects in the queue, returning an array of the// objects in the Queue, or an empty array if the queue is empty.// The order of elements in the array is first in to last in, the same// order produced by successive calls to Dequeue.public virtual Object[] ToArray(){Object[] arr = new Object[_size];if (_size==0)return arr;if (_head < _tail) {Array.Copy(_array, _head, arr, 0, _size);} else {Array.Copy(_array, _head, arr, 0, _array.Length - _head);Array.Copy(_array, 0, arr, _array.Length - _head, _tail);}return arr;}// PRIVATE Grows or shrinks the buffer to hold capacity objects. Capacity// must be >= _size.private void SetCapacity(int capacity) {Object[] newarray = new Object[capacity];if (_size > 0) {if (_head < _tail) {Array.Copy(_array, _head, newarray, 0, _size);} else {Array.Copy(_array, _head, newarray, 0, _array.Length - _head);Array.Copy(_array, 0, newarray, _array.Length - _head, _tail);}}_array = newarray;_head = 0;_tail = (_size == capacity) ? 0 : _size; _version++;}public virtual void TrimToSize(){SetCapacity(_size);}// Implements a synchronization wrapper around a queue.[Serializable]private class SynchronizedQueue : Queue{private Queue _q;private Object root;internal SynchronizedQueue(Queue q) {this._q = q;root = _q.SyncRoot;}public override bool IsSynchronized {get { return true; }}public override Object SyncRoot {get {return root;}}public override int Count { get { lock (root) {return _q.Count;} }}public override void Clear() {lock (root) {_q.Clear();}}public override Object Clone() {lock (root) {return new SynchronizedQueue((Queue)_q.Clone());}}public override bool Contains(Object obj) {lock (root) {return _q.Contains(obj);}}public override void CopyTo(Array array, int arrayIndex) {lock (root) {_q.CopyTo(array, arrayIndex);}}public override void Enqueue(Object value) {lock (root) {_q.Enqueue(value);}}[SuppressMessage("Microsoft.Contracts", "CC1055")] // Thread safety problems with precondition - can't express the precondition as of Dev10.public override Object Dequeue() {lock (root) {return _q.Dequeue();}}public override IEnumerator GetEnumerator() {lock (root) {return _q.GetEnumerator();}}[SuppressMessage("Microsoft.Contracts", "CC1055")] // Thread safety problems with precondition - can't express the precondition as of Dev10.public override Object Peek() {lock (root) {return _q.Peek();}}public override Object[] ToArray() {lock (root) {return _q.ToArray();}}public override void TrimToSize() {lock (root) {_q.TrimToSize();}}} // Implements an enumerator for a Queue. The enumerator uses the// internal version number of the list to ensure that no modifications are// made to the list while an enumeration is in progress.[Serializable]private class QueueEnumerator : IEnumerator, ICloneable{private Queue _q;private int _index;private int _version;private Object currentElement;internal QueueEnumerator(Queue q) {_q = q;_version = _q._version;_index = 0;currentElement = _q._array;if (_q._size == 0)_index = -1;}public Object Clone(){return MemberwiseClone();}public virtual bool MoveNext() {if (_version != _q._version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));if (_index < 0) { currentElement = _q._array;return false;}currentElement = _q.GetElement(_index);_index++;if (_index == _q._size)_index = -1;return true;}public virtual Object Current {get {if (currentElement == _q._array){if (_index == 0)throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));elsethrow new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));}return currentElement;}}public virtual void Reset() {if (_version != _q._version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));if (_q._size == 0)_index = -1;else_index = 0;currentElement = _q._array;}}internal class QueueDebugView {private Queue queue; public QueueDebugView( Queue queue) {if( queue == null)throw new ArgumentNullException("queue");Contract.EndContractBlock();this.queue = queue;}[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]public Object[] Items { get {return queue.ToArray();}}} }
}
源码测试
https://github.com/luoyikun/UnityForTest
MyQueue.cs
C#:数据结构queue队列源码:循环使用数组头标,尾标,防止不停扩容数组相关推荐
- 并发编程5:Java 阻塞队列源码分析(下)
上一篇 并发编程4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...
- android handler2--消息队列源码解析
android handler2–消息队列源码解析 1.Looper 对于Looper主要是prepare()和loop()两个方法. 首先看prepare()方法 public static fin ...
- java-List集合的源码分析(数据结构方面,源码注释方面),迭代器快速失败机制
List实现了Collection接口,产生三个子类:ArrayList,LinkedList,Vector 文章包含解释方面: 数据结构方面, 源码注释方面&迭代器快速失败机制 方面1-基于 ...
- Squid 代理服务器 编译源码 伪造HTTP_X_FORWARDED_FOR 请求头
本实验操作系统选用 CentOS release 5.6 (Final) 实验目的实现 Squid 代理服务器 编译源码 伪造HTTP_X_FORWARDED_FOR 请求头 .使其显示任意IP 过 ...
- 旺旺打标原理,旺旺打标有什么影响,旺旺打标是什么,魔搜打标,旺旺打标源码,旺旺搜索打标、旺旺打标对应服务上场接口、魔搜,服务市场的搜索接口,足迹接口,旺旺打标 淘宝打标 魔搜打标
旺旺打标原理,旺旺打标有什么影响,旺旺打标是什么,旺旺打标源码,旺旺搜索打标.旺旺打标对应服务上场接口 , 其实旺旺搜索打标,魔搜使用的原理是利用手淘搜索接口和足迹接口的缓存机制进行实现 请求方式: ...
- 并发-阻塞队列源码分析
阻塞队列 参考: http://www.cnblogs.com/dolphin0520/p/3932906.html http://endual.iteye.com/blog/1412212 http ...
- Java语法理论和面经杂疑篇《七. 数据结构与集合源码》
目录 1. 数据结构剖析 1.1 研究对象一:数据间逻辑关系 1.2 研究对象二:数据的存储结构(或物理结构) 1.3 研究对象三:运算结构 1.4 小结 2. 一维数组 2.1 数组的特点 2.2 ...
- 【队列源码研究】消息队列beanstalkd源码详解
顺风车运营研发团队 李乐 1.消息队列简介 计算机软件发展的一个重要目标是降低软件耦合性: 网站架构中,系统解耦合的重要手段就是异步,业务之间的消息传递不是同步调用,而是将一个业务操作分为多个阶段,每 ...
- 每日一博 - DelayQueue阻塞队列源码解读
文章目录 Pre DelayQueue特征 Leader/Followers模式 DelayQueue源码分析 类继承关系 核心方法 成员变量 构造函数 入队方法 offer(E e) 出队方法 po ...
最新文章
- 核心板焊接之连接器与邮票孔
- Linux下命令执行顺序控制与管道
- 卡尔曼滤波(kalman)相关理论以及与HMM、最小二乘法关系 转
- mysql数据库DDL操作
- 使用MASM02 - Win32汇编语言010
- 【JAVASCRIPT】处理剪切板
- ELK学习9_ELK数据流传输过程_问题总结2
- (Mysql)连接问题之1130
- python3 打印目录下所有模块_python3基础12详解模块和包(库)|构建|使用
- LeetCode 759. 员工空闲时间(排序)
- 生成.o linux,JaxoDraw下载 费曼图生成工具JaxoDraw for linux v2.1.0 官方安装版 下载-脚本之家...
- 【写给以前的自己】python中,既生list何生tuple?简论学习数据结构(e.g.哈希化)对自己的提升
- 小白重装系统教程_小白重装系统使用教程
- ios 录音生成.aac录音文件
- 【干货】9个网络故障排除经典案例,网工都得会
- ​红旗首款奢华纯电动SUV车型上市;一起教育登陆纳斯达克;恒隆与凯悦在昆明打造君悦酒店 | 美通企业周刊...
- 炒鸡福利:买云服务送智能摄像头
- 分享时刻—今日一收获
- 2022年度总结——2022我在CSDN的那些事暨2023我的目标展望:Pursue freedom Realize self-worth
- 微积分入门:无穷小之比与无穷小求和
热门文章
- 美国专利及引用被引用数据
- 电力通讯网络安全分区隔离配置——科东StoneWall-2000网络安全隔离设备(正,反向) 隔离内外网络
- 【soc】bootrom注意事项
- 爬虫案例:ajax异步加载,爬取豆瓣电影排行榜
- 高维多元时序数据聚类
- sql server导入mdf与ldf文件
- 谁偷偷删了你的微信?别慌!Python 帮你都揪出来了
- php案例分析百度云_案例 | QQ 音乐还是网易云音乐?看完分析,你会选哪一个?...
- c语言程序设计学生管理系统,c语言程序设计报告学生信息管理系统
- ARM TK1 安装ROS- indigo