栈中二三事

   在平时唠嗑的时候,总是会听到有大神说,线程栈,函数栈,值类型是存在栈上的等等,好多关于栈的词,大家对这些有兴趣的,且听我慢慢道来。

 (一)栈的定义

        说起栈,感觉第一个反应就是明修栈道,暗度陈仓...。有一点数据结构的基础同学都知道栈就是先进后出的线性表,其实栈在我们生活中,就像类似洗盘子,先洗的盘子,一个个堆叠起来,拿的时候,从上面第一个开始拿,这就是典型的栈的结构:“后进者,先出,先进者,后出”。

 (二)为什么会有栈这种数据结构呢

  很多人可能会有这样的疑问,栈,这种先进后出的特点,我用数组,链表也可以实现呀,为啥要有栈的(感觉在编程的世界里面,很多的事情都是类似这样的,C#里面的委托一样,先给一个委托delegate关键字,然后再给一个Func,Action)。我觉得大概是这样的:很多时候,也许你用一个delegate关键字,可能是无所不能,很自由,太多的自由就会导致很难统一。数组和链表也是类似的,很自由,可以随意的两端的插入和删除数据,而栈呢,是等于对特定的场景进行抽象。这可能也是我们编程中很少用到栈的原因把。

    (三) 栈的实现

   固定大小的栈的复杂度分析,下面是固定大小的栈的实现。这种结构的入栈和出栈的时间复杂度都是O(1)。空间复杂度也是O(1)。特别提醒:空间复杂度是除了原来本身需要的空间之外所需要占用的空间

    public class ArrayStack<T>
    {
        private int _currentIndex;
        private T[] _item;
        public int Count { get; set; }

        public ArrayStack(int n)
        {
            _item = new T[n];
            this.Count = n;
            _currentIndex = 0;
        }

        public void Push(T item)
        {
            _item[_currentIndex] = item;
            _currentIndex++;
            this.Count++;
        }

        public T Pop()
        {
            if (_currentIndex == 0)
            {
                return default(T);
            }
            var item = _item[_currentIndex - 1];
            _currentIndex--;
            _item[_currentIndex] = default(T);
            this.Count--;
            return item;
        }
    }

      可以动态调整大小的栈

public class ResizeStack<T>
    {
        //
        private int _defaultSiez = 4;
        private T[] _item;
        private int _currentIndex;

        /// <summary>
        /// 不指定大小
        /// </summary>
        public ResizeStack()
        {
            _item = new T[_defaultSiez];
            _currentIndex = 0;
        }

        /// <summary>
        /// 指定大小
        /// </summary>
        /// <param name="n"></param>
        public ResizeStack(int n)
        {
            _item = new T[n];
            _currentIndex = 0;
        }


        public void Push(T t)
        {
            if (_currentIndex >= this._item.Length / 2)
            {
                var arr = new T[this._item.Length * 2];
                _item.CopyTo(arr,0);
                _item = arr;
            }
            _item[_currentIndex] = t;
            _currentIndex++;
        }

        public T Pop()
        {
            var value = default(T);
            if (_currentIndex == 0)
            {
                return value;
            }
             value=_item[_currentIndex - 1];
             _item[_currentIndex-1]=default(T);
            _currentIndex--;
            return value;
        }

        public int Count => this._currentIndex+1;


    }

      链式栈的实现

     

     (四)栈的案例

   逆波兰表达式,括号匹配等等

   

posted @ 2019-03-04 22:28  GDOUJKZZ  阅读(205)  评论(0编辑  收藏  举报