• 栈中二三事


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

     (一)栈的定义

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

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

      很多人可能会有这样的疑问,栈,这种先进后出的特点,我用数组,链表也可以实现呀,为啥要有栈的(感觉在编程的世界里面,很多的事情都是类似这样的,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;
    
    
        }

          链式栈的实现

         

         (四)栈的案例

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

       

  • 相关阅读:
    Django匆匆一眼却解答了多年疑惑
    2020年度总结,似乎没有什么大的长进,似乎也得到了一些收获
    Django搭建示例项目实战与避坑细节
    真香,理解记忆法学习Python基础语法
    如何让文科生5分钟写上Python
    Django官方为什么没有标准项目结构
    用PyCharm打个专业的招呼
    MySQL/MariaDB读写分离配置
    Mysql/Mariadb主从复制
    图解CentOS系统启动流程
  • 原文地址:https://www.cnblogs.com/gdouzz/p/10473731.html
Copyright © 2020-2023  润新知