zoukankan      html  css  js  c++  java
  • 栈中二三事

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

     (一)栈的定义

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

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

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

          链式栈的实现

         

         (四)栈的案例

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

       

  • 相关阅读:
    让linux用户隶属于多个组
    ldd 的介绍
    全栈博客开发(三)完善项目并容器化
    C++ 迭代器
    C++ vector类
    C++输入输出流和变量
    C++ vscode搭建windows C++开发环境
    全栈博客开发(二)添加渲染
    C++ string类
    全栈博客开发(一)服务结构
  • 原文地址:https://www.cnblogs.com/gdouzz/p/10473731.html
Copyright © 2011-2022 走看看