## 基本数据结构解析之Stack & Queue

### Stack:

##### 构造函数(初始化)

Stack() / Stack(int initialCapacity) / Stack(ICollection col) : this((col==null ? 32 : col.Count))

   1: private Object[] _array;     // Storage for stack elements
   2: private int _size;           // Number of items in the stack.
   3: private int _version;        // Used to keep enumerator in sync w/ collection.
   4:
   5: private const int _defaultCapacity = 10;
   6:
   7: public Stack() {
   8:     _array = new Object[_defaultCapacity];
   9:     _size = 0;
  10:     _version = 0;
  11: }
  12:
  13: // Create a stack with a specific initial capacity.  The initial capacity
  14: // must be a non-negative number.
  15: public Stack(int initialCapacity) {
  16:     if (initialCapacity < 0)
  17:         throw new ArgumentOutOfRangeException("initialCapacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  18:     if (initialCapacity < _defaultCapacity)
  19:         initialCapacity = _defaultCapacity;  // Simplify doubling logic in Push.
  20:     _array = new Object[initialCapacity];
  21:     _size = 0;
  22:     _version = 0;
  23: }

#### Push/Pop

Push: 如果数据达到最大容量，则分配到容量*2新的数组，并将原来的数据拷贝到新数组, 之后将栈顶设为对应的值，而后栈顶索引自加

   1: // Pushes an item to the top of the stack.
   2: //
   3: public virtual void Push(Object obj) {
   4:     if (_size == _array.Length) {
   5:         Object[] newArray = new Object[2*_array.Length];
   6:         Array.Copy(_array, 0, newArray, 0, _size);
   7:         _array = newArray;
   8:     }
   9:     _array[_size++] = obj;
  10:     _version++;
  11: }

#### Pop: 将栈顶设为null, 索引自减

   1: // Pops an item from the top of the stack.  If the stack is empty, Pop
   2: // throws an InvalidOperationException.
   3: public virtual Object Pop() {
   4:     if (_size == 0)
   5:         throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EmptyStack"));
   6:     _version++;
   7:     Object obj = _array[--_size];
   8:     _array[_size] = null;     // Free memory quicker.
   9:     return obj;
  10: }

#### Contains - 按索引进行顺序比较

   1: public virtual bool Contains(Object obj) {
   2:     int count = _size;
   3:
   4:     while (count-- > 0) {
   5:         if (obj == null) {
   6:             if (_array[count] == null)
   7:                 return true;
   8:         }
   9:         else if (_array[count] != null && _array[count].Equals(obj)) {
  10:             return true;
  11:         }
  12:     }
  13:     return false;
  14: }

#### Clear

   1: public virtual void Clear() {
   2:     Array.Clear(_array, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
   3:     _size = 0;
   4:     _version++;
   5: }
   6:
   7: [MethodImplAttribute(MethodImplOptions.InternalCall)]
   8: [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
   9: public static extern void Clear(Array array, int index, int length);
  10:

#### Clone - 深拷贝, 直接复制数据到新的栈数组中

   1: public virtual Object Clone() {
   2:     Stack s = new Stack(_size);
   3:     s._size = _size;
   4:     Array.Copy(_array, 0, s._array, 0, _size);
   5:     s._version = _version;
   6:     return s;
   7: }

### Queue:

   1: // Creates a queue with room for capacity objects. The default initial
   2: // capacity and grow factor are used.
   3: public Queue()
   4:     : this(32, (float)2.0) {
   5: }
   6:
   7: // Creates a queue with room for capacity objects. The default grow factor
   8: // is used.
   9: //
  10: public Queue(int capacity)
  11:     : this(capacity, (float)2.0) {
  12: }
  13:
  14: // Creates a queue with room for capacity objects. When full, the new
  15: // capacity is set to the old capacity * growFactor.
  16: //
  17: public Queue(int capacity, float growFactor) {
  18:     if (capacity < 0)
  19:         throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  20:     if (!(growFactor >= 1.0 && growFactor <= 10.0))
  21:         throw new ArgumentOutOfRangeException("growFactor", Environment.GetResourceString("ArgumentOutOfRange_QueueGrowFactor", 1, 10));
  22:
  23:     _array = new Object[capacity];
  24:     _head = 0;
  25:     _tail = 0;
  26:     _size = 0;
  27:     _growFactor = (int)(growFactor * 100);
  28: }

   1: Queue q = new Queue(10, 2);
   2: for(int i=0; i<q; i++)
   3: {
   4:     e.EnQueue(i);
   5: }
   6:
   7: e.EnQueue(3); // The Capbility size will be 20

#### Enque

   1: // Adds obj to the tail of the queue.
   2: //
   3: public virtual void Enqueue(Object obj) {
   4:     if (_size == _array.Length) {
   5:         int newcapacity = (int)((long)_array.Length * (long)_growFactor / 100);
   6:         if (newcapacity < _array.Length + _MinimumGrow) {
   7:             newcapacity = _array.Length + _MinimumGrow;
   8:         }
   9:         SetCapacity(newcapacity);
  10:     }
  11:
  12:     _array[_tail] = obj;
  13:     _tail = (_tail + 1) % _array.Length;
  14:     _size++;
  15:     _version++;
  16: }

#### DeQueue

   1: // Removes the object at the head of the queue and returns it. If the queue
   2: // is empty, this method simply returns null.
   3: public virtual Object Dequeue() {
   4:     if (_size == 0)
   5:         throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EmptyQueue"));
   6:
   7:     Object removed = _array[_head];
   8:     _array[_head] = null;
   9:     _head = (_head + 1) % _array.Length;
  10:     _size--;
  11:     _version++;
  12:     return removed;
  13: }

#### Clear

   1: // Removes all Objects from the queue.
   2: public virtual void Clear() {
   3:     if (_head < _tail)
   4:         Array.Clear(_array, _head, _size);
   5:     else {
   6:         Array.Clear(_array, _head, _array.Length - _head);
   7:         Array.Clear(_array, 0, _tail);
   8:     }
   9:
  10:     _head = 0;
  11:     _tail = 0;
  12:     _size = 0;
  13:     _version++;
  14: }

#### Clone 深拷贝

   1: public virtual Object Clone() {
   2:    Queue q = new Queue(_size);
   3:    q._size = _size;
   4:
   5:    int numToCopy = _size;
   6:    int firstPart = (_array.Length - _head < numToCopy) ? _array.Length - _head : numToCopy;
   7:    Array.Copy(_array, _head, q._array, 0, firstPart);
   8:    numToCopy -= firstPart;
   9:    if (numToCopy > 0)
  10:        Array.Copy(_array, 0, q._array, _array.Length - _head, numToCopy);
  11:
  12:    q._version = _version;
  13:    return q;
  14: }

### 未完待续

posted on 2008-11-29 19:05  xwang  阅读(...)  评论(... 编辑 收藏

• 随笔 - 92
• 文章 - 0
• 评论 - 252
• 引用 - 22