2. 背包,队列和栈

  许多基础数据类型都和对象的集合有关。数据类型的值就是一组对象的集合,所有操作都是关于添加,删除或是访问集合中的对象。背包(Bag),队列(Quene)和栈(Stack) 它们的不同之处在于删除或者访问对象的顺序不同。

  

  1. API

  

2. 背包,队列和栈

  Stack 和 Quene 都含有一个能够删除集合中特定元素的方法。

  实现上面API需要高级语言的特性:泛型,装箱拆箱,可迭代(实现 IEnumerable 接口)。

  

  1. 背包

  背包是一种不支持从中删除元素的集合类型——它的目的就是帮助用例收集元素并迭代遍历所有元素。用例也可以使用栈或者队列,但使用 Bag 可以说明元素的处理顺序不重要。

  

  2.先进先出队列

  队列是基于先进先出(FIFO)策略的集合类型。

 

  3. 下压栈

  下压栈(简称栈)是一种基于后进先出(LIFO)策略的集合类型。

  应用例子:计算输入字符串  (1+((2+3)*(4*5)))表达式的值。

  使用双栈解决:

    1. 将操作数压入操作数栈;

    2. 将运算符压入运算符栈;

    3. 忽略做括号;

    4. 在遇到右括号时,弹出一个运算符,弹出所需数量的操作数,并将运算符和操作数的运算结果压入操作数栈。

 

  2.用数组实现

  实现下压栈:

//想要数据类型可迭代,需要实现IEnumerable public class ResizingStack<Item> : IEnumerable<Item> { private Item[] a = new Item[1]; private int N = 0; public bool IsEmpty{ get { return N == 0; } } public int Size { get { return N; } } public int Count { get; set; } /// <summary> /// 使数组处于半满 /// </summary> /// <param></param> private void Resize(int max) { Count = 0; Item[] temp = new Item[max]; for(var i = 0;i<N;i++) { temp[i] = a[i]; Count++; } a = temp; } public void push(Item item) { if (N == a.Length) Resize(a.Length * 2); a[N++] = item; } public Item Pop() { Item item = a[--N]; a[N] = default(Item); //避免对象游离 if (N > 0 && N == a.Length / 4) Resize(a.Length/2); return item; } IEnumerator<Item> IEnumerable<Item>.GetEnumerator() { return new ResizingStackEnumerator<Item>(a); } public IEnumerator GetEnumerator() { return new ResizingStackEnumerator<Item>(a); } } class ResizingStackEnumerator<Item> : IEnumerator<Item> { private Item[] a; private int N = 0; public ResizingStackEnumerator(Item[] _a) { a = _a; N = a.Length-1; } public object Current => a[N--]; Item IEnumerator<Item>.Current => a[N--]; public void Dispose() { throw new NotImplementedException(); } public bool MoveNext() { return N > 0; } public void Reset() { throw new NotImplementedException(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzsxf.html