zoukankan      html  css  js  c++  java
  • C# Queue 和Stack的实现

    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 < 0)
                    ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired);
        
                _array = new T[capacity];
                _head = 0;
                _tail = 0;
                _size = 0;
            }
            
            public Queue(IEnumerable<T> collection)
            {
                if (collection == null)
                    ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
    
                _array = new T[_DefaultCapacity];
                _size = 0;
                _version = 0;
    
                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 / 100);
                    if (newcapacity < _array.Length + _MinimumGrow) {
                        newcapacity = _array.Length + _MinimumGrow;
                    }
                    SetCapacity(newcapacity);
                }
        
                _array[_tail] = item;
                _tail = (_tail + 1) % _array.Length;
                _size++;
                _version++;
            }
            
            public T Dequeue() {
                if (_size == 0)
                    ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyQueue);
        
                T removed = _array[_head];
                _array[_head] = default(T);
                _head = (_head + 1) % _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-- > 0) {
                    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 + 1) % _array.Length;
                }
        
                return false;
            }  
            
            private void SetCapacity(int capacity) {
                T[] newarray = new T[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++;
            }        
    }

    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 < 0)
                    ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired);
                    _array = new T[capacity];
                    _size = 0;
                    _version = 0;
                  }
            
            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, 0);  
                    _size = count;
                }    
                else {                
                    _size = 0;
                    _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 == 0) ? _defaultCapacity : 2*_array.Length];
                    Array.Copy(_array, 0, newArray, 0, _size);
                    _array = newArray;
                }
                _array[_size++] = item;
                _version++;
            }
        
           public T Pop() {
                if (_size == 0)
                    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-- > 0) {
                    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里面的每个元素

  • 相关阅读:
    Mongoexport导出数据,Mongoimport导入数据,mongodump备份数据,mongorestore恢复恢复
    php7中使用mongodb的驱动
    windows(X64)+apche2.4+php7.2下安装mongodb
    windows(X64)下安装apche2.4+php7.2+mysql5.7
    Django2.0 path与Django1.x版本url正则匹配问题
    Django: ImportError: No module named 'corsheaders'
    linux开启端口
    MySQL 存储过程传参数实现where id in(1,2,3,...)示例
    ubuntu安装pip3
    在Ubuntu 16.04 安装python3.6 环境并设置为默认
  • 原文地址:https://www.cnblogs.com/majiang/p/7878349.html
Copyright © 2011-2022 走看看