Queue 和Stack的使用就不用多说吧,一个是先进先出,一个是后进先出。 这里我主要关注其实现原理。

queue的实现如下:

 public class Queue<T> : IEnumerable<T>,System.Collections.ICollection,IReadOnlyCollection<T> {
private T[] _array;
private int _head; // First valid element in the queue
private int _tail; // Last valid element in the queue
private int _size; // Number of elements. public Queue(int capacity) {
if (capacity < )
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired); _array = new T[capacity];
_head = ;
_tail = ;
_size = ;
} public Queue(IEnumerable<T> collection)
{
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection); _array = new T[_DefaultCapacity];
_size = ;
_version = ; using(IEnumerator<T> en = collection.GetEnumerator()) {
while(en.MoveNext()) {
Enqueue(en.Current);
}
}
} public void Enqueue(T item) {
if (_size == _array.Length) {
int newcapacity = (int)((long)_array.Length * (long)_GrowFactor / );
if (newcapacity < _array.Length + _MinimumGrow) {
newcapacity = _array.Length + _MinimumGrow;
}
SetCapacity(newcapacity);
} _array[_tail] = item;
_tail = (_tail + ) % _array.Length;
_size++;
_version++;
} public T Dequeue() {
if (_size == )
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyQueue); T removed = _array[_head];
_array[_head] = default(T);
_head = (_head + ) % _array.Length;
_size--;
_version++;
return removed;
} public bool Contains(T item) {
int index = _head;
int count = _size; EqualityComparer<T> c = EqualityComparer<T>.Default;
while (count-- > ) {
if (((Object) item) == null) {
if (((Object) _array[index]) == null)
return true;
}
else if (_array[index] != null && c.Equals(_array[index], item)) {
return true;
}
index = (index + ) % _array.Length;
} return false;
} private void SetCapacity(int capacity) {
T[] newarray = new T[capacity];
if (_size > ) {
if (_head < _tail) {
Array.Copy(_array, _head, newarray, , _size);
} else {
Array.Copy(_array, _head, newarray, , _array.Length - _head);
Array.Copy(_array, , newarray, _array.Length - _head, _tail);
}
} _array = newarray;
_head = ;
_tail = (_size == capacity) ? : _size;
_version++;
}
}

Stack的实现:

 public class Stack<T> : IEnumerable<T>, System.Collections.ICollection,IReadOnlyCollection<T>
{
private T[] _array; // Storage for stack elements
private int _size; // Number of items in the stack. public Stack(int capacity) {
if (capacity < )
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired);
_array = new T[capacity];
_size = ;
_version = ;
} public Stack(IEnumerable<T> collection)
{
if (collection==null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection); ICollection<T> c = collection as ICollection<T>;
if( c != null) {
int count = c.Count;
_array = new T[count];
c.CopyTo(_array, );
_size = count;
}
else {
_size = ;
_array = new T[_defaultCapacity]; using(IEnumerator<T> en = collection.GetEnumerator()) {
while(en.MoveNext()) {
Push(en.Current);
}
}
}
} public void Push(T item) {
if (_size == _array.Length) {
T[] newArray = new T[(_array.Length == ) ? _defaultCapacity : *_array.Length];
Array.Copy(_array, , newArray, , _size);
_array = newArray;
}
_array[_size++] = item;
_version++;
} public T Pop() {
if (_size == )
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyStack);
_version++;
T item = _array[--_size];
_array[_size] = default(T); // Free memory quicker.
return item;
} public bool Contains(T item) {
int count = _size; EqualityComparer<T> c = EqualityComparer<T>.Default;
while (count-- > ) {
if (((Object) item) == null) {
if (((Object) _array[count]) == null)
return true;
}
else if (_array[count] != null && c.Equals(_array[count], item) ) {
return true;
}
}
return false;
}
}

Queue 和Stack都是依靠数组来实现,并且都有带int capacity的构造函数。假如我们定义一个数组长度为5,Queue 和Stack都添加了5个元素,现在需要移除2个元素,Queue 移除arr[0],arr[1]两个元素(移除通过下标_head+1完成的),Stack移除arr[4],arr[3]两个元素(通过_size-1完成的),现在再添加2个元素,Queue 的arr5个元素都已被占用,需要创建新的数组,并且把原先3,4,5个元素拷贝到新的数组里面,但是Stack就好很多,新增加的元素可以直接赋值到arr[3],arr[4],查找Contains方法的实现都是循环数组arr里面的每个元素

C# Queue 和Stack的实现的更多相关文章

  1. Scala 深入浅出实战经典 第39讲:ListBuffer、ArrayBuffer、Queue、Stack操作代码实战

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  2. C++关于vector、queue、stack、priority_queue的元素访问

    vector.queue.stack.priority_queue对元素进行元素访问时,返回的是对应元素的引用.

  3. ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  4. 数据结构与算法(4) -- list、queue以及stack

    今天主要给大家介绍几种数据结构,这几种数据结构在实现原理上较为类似,我习惯称之为类list的容器.具体有list.stack以及queue. list的节点Node 首先介绍下node,也就是组成li ...

  5. C#10在List, Queue 以及Stack中使用EnsureCapacity方法来提升性能

    简介 在今天的文章中,我们将介绍 C# 10 中引入的一项新功能.这是已添加到 List.Queue 和 Stack 集合中的 EnsureCapacity 方法.我们将讨论为什么我们应该使用这个方法 ...

  6. deque、queue和stack深度探索(下)

    deque如何模拟连续空间?通过源码可以看到这个模型就是通过迭代器来完成. 迭代器通过重载操作符+,-,++,--,*和->来实现deque连续的假象,如上图中的 finish-start ,它 ...

  7. Queue及Stack

    Queue 她是一个接口,有多冢实现方式(LinkedList.ArrayDeque等) 类别 方法 入队 add.offer(优先级高) 出队 remove.poll 查询 element.peek ...

  8. Map、Set、List、Queue、Stack的特点与用法

    Collection          接口的接口   对象的集合 ├ List                   子接口      按进入先后有序保存   可重复 │├ LinkedList    ...

  9. .NET中的Queue和Stack

    1.ArrayList类 ArrayList类主要用于对一个数组中的元素进行各种处理.在ArrayList中主要使用Add.Remove.RemoveAt.Insert四个方法对栈进行操作.Add方法 ...

随机推荐

  1. 配置本地无密码 SSH登录远程服务器

    下面这幅图简单来说就是你本地有一把钥匙,服务器也有一把钥匙,当登录的时候本地的钥匙与服务器的进行对比,通过算法的判定,监测是否具有权限的用户 第一步,在本地配置这把钥匙生成私钥与公钥: 打开.ssh目 ...

  2. poj2828 伸展树模拟

    用伸展树模拟插队比线段树快乐3倍.. 但是pojT了.别的oj可以过,直接贴代码. 每次更新时,找到第pos个人,splay到根,然后作为新root的左子树即可 #include<iostrea ...

  3. 兼容IE8以下,获取className节点的元素(document.getElementsByClassName()兼容写法)。

    因为ie8一下不兼容                 document.getElementsByClassName()                 功能:通过class的名字获取符合条件的元素 ...

  4. Windows10 Compatibility Telemetry(CompatTelRunner.exe) 占用硬盘100%

    相信很多人跟我一样总被Compatibility Telemetry(CompatTelRunner.exe) 占用硬盘100%困扰,Compatibility Telemetry翻译过来就是“微软兼 ...

  5. [转] HTML5 FormData 方法介绍以及实现文件上传

    XMLHttpRequest 是一个浏览器接口,通过它,我们可以使得 Javascript 进行 HTTP (S) 通信.XMLHttpRequest 在现在浏览器中是一种常用的前后台交互数据的方式. ...

  6. day8--socket文件传输

    FTP server 1.读取文件名 2.检测文件是否存在 3.打开文件 4.检测文件大小(告诉客户端发送文件的大小) 5.发送文件大小和MD5值给客户端,MD5 6.等待客户端确认(防止粘包) 7. ...

  7. k8s 环境搭建

    转自:https://blog.csdn.net/running_free/article/details/78388948 一.概述 1.简介 官方中文文档:https://www.kubernet ...

  8. BZOJ3626 [LNOI2014]LCA 树链剖分 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3626 题意概括 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节 ...

  9. HDU4857 逃生 拓扑排序

    Problem Description糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同 ...

  10. Centos7与Windows10添加Windows10启动项并设置为默认启动

    在Centos7下root登陆 编辑 /boot/grub2/grub.cfg vim /boot/grub2/grub.cfg 在第一行添加 menuentry "Windows10&qu ...