• 数据结构学习之栈


    开篇:上次我们学习了基本的数组结构。

    今天,我们来学习另一个线性的数据结构,栈。

    栈这种数据结构,无时无刻不在我们的身边。是种极其重要的数据结构。

    所以,什么是栈呢?(不要废话了,快说)

    先来看我们生活中,比如我们经常操作的word文档。

    我们比如写入四个字, (天气真好)。

    我们不想要了这句话,Ctrl+Z 回撤掉我们所打的。你会很自然发现,消失的顺序会是,好->真->气->天。

    别急。 我们再来个例子。

    比如那我们的函数调用,

    计算机需要有个系统栈来记录我们的函数调用。

    public void A()
    {
            B();
    }
    
    public void B()
    {
            C();
    }
    
    public void C()
    {
            //....
    }

    A为我们的主函数,当A调用B的时候,进入B函数时,会在A函数中断的位置把函数地址信息压入到系统栈里。

    此时B函数又在用掉C函数,此时又会在B函数中断的位置把函数地址信息压入到系统栈里。

    此时C执行完后,该怎么办呢。此时系统栈里会取出栈顶元素为返回的地址,为B,程序便正确的回到B处。

    同样的。B执行完,系统栈又会取出栈顶元素为返回的地址,为A,程序便正确的回到A处。

    此时我们正完成了我们的函数调用。

    如我们的图所示:

    所以。栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。

    插入和删除都在栈顶这一端操作。

    包括我们的经常使用编程的Ide,会自动检查括号的匹配等等。都是基于栈的结构。

    现在,我们基于我们上次的线性数组。来实现我们的自定义栈结构。

    我们让我们的结构实现我们的泛型IStack接口来实现。

    分别有pop出栈,push入栈。判断是否为空和清空操作等。

    /// <summary>
        ////// </summary>
        /// <typeparam name="T"></typeparam>
        public interface IStack<T>
        {
            void Push(T value);
            T Pop();
            T Peek();
            bool IsEmpty();
            void Clear();
        }
    
        public class Stack<T> : IStack<T>
        {
            private Array<T> Data;
            public Stack(int capacity=20)
            {
                this.Data = new Array<T>(capacity);
            }
    
            public void Clear()
            {
                this.Data.SetEmpty();
            }
    
            public bool IsEmpty()
            {
                return this.Data.GetSize() == 0;
            }
    
            public T Peek()
            {
                return this.Data.Search(this.Data.GetSize());
            }
    
            public T Pop()
            {
                return this.Data.Delete(this.Data.GetSize());
            }
    
            public void Push(T value)
            {
                this.Data.Add(value);
            }
        }

    由此可见。这是一个重要的数据结构。

    届时,我们来看看leetcode上的一道典型的链表题目。20题

    题目是这样的。

    给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

    有效字符串需满足:

    左括号必须用相同类型的右括号闭合。
    左括号必须以正确的顺序闭合。
    注意空字符串可被认为是有效字符串。

    先给出代码(C#)。

    public class Solution {
        public bool IsValid(string str) {
            var stack = new Stack();
                for (int i = 0; i < str.Length; i++)
                {
                    if (str[i] == '[' || str[i] == '{' || str[i] == '(')
                        stack.Push(str[i]);
                    else if(str[i] == ']' || str[i] == '}' || str[i] == ')')
                    {
                        if (stack.Count == 0)
                            return false;
                        var top = (char)stack.Pop();
                        if (str[i] == ')' && top != '(')
                            return false;
                        if (str[i] == ']' && top != '[')
                            return false;
                        if (str[i] == '}' && top != '{')
                            return false;
                    }
                }
                return stack.Count==0;
        }
    }
    使用的Stack类为我们的C#本身为我们提供的栈结构。
    本题目是 [,(,,{ 三种括号的匹配。
    我们判断。如果是这三种,我们就相应的入栈。当遇到他们所匹配的结尾括号时,],),}时候。
    便相应的出栈。如果不是他们对应的标签。便是不符合要求的。当一一遍历出栈后。
    如果栈为空时。便说明便是符合要求的。

    今天我们的栈就到这里啦,下一次,我们来实现另一种线性结构,队列。
  • 相关阅读:
    Android源码编译jar包BUILD_JAVA_LIBRARY 与BUILD_STATIC_JAVA_LIBRARY的区别(一)
    模块化开发
    最近理解记忆
    ES6语法—— 模块化开发之import和export命令详解
    关于阿里图标库Iconfont生成图标的三种使用方式(fontclass/unicode/symbol)
    2.新知-display:inline-block元素之间空隙的产生原因和解决办法
    规避同源
    vue总结
    vue组件通信
    vue 多次学习
  • 原文地址:https://www.cnblogs.com/GuanZx/p/11048388.html
Copyright © 2020-2023  润新知