作者: OOM_Killer | 来源:发表于2019-08-18 19:38 被阅读0次

如何理解栈

栈其实十分好理解,后进者先出,先进者后出,就是典型的栈的结构。


2019-08-18 17-15-13屏幕截图.png

当一个数据只涉及在一端插入和删除数据,并且满足后进先出、先进后出的特性,就应该选择“栈”这种数据结构。

如何实现一个栈

栈有 顺序栈链式栈 。顺序栈是由数组实现的,而链式栈是由链表实现的。
有了实现方式还差栈的最常规操作,出栈和入栈。这里利用数组实现一个顺序栈。

顺序栈

一个最基础的顺序栈 实现(使用golang)

type ArrayStack struct {
    Item  []string     // 数组
    Cnt   int          // 栈中元素个数
    n     int          // 栈的大小
}

func (s *ArrayStack) InitStack(n int) {
    s.Item  = make([]string,n)
    s.n     = n
    s.Cnt   = 0
}

// 入栈操作
func (s *ArrayStack) Push(item string) error {
    // 数组空间不够了,直接返回 error , 入栈失败
    if s.Cnt == s.n {
        return errors.New("The Stack Is Full.")
    }
    s.Item[s.Cnt] = item
    s.Cnt++
    return nil
}

// 出栈操作
func (s *ArrayStack) Pop() (string,error) {
    // 栈为空,直接返回 error , 出栈失败
    if s.Cnt == 0 {
        return "",errors.New("The Stack Is Empty.")
    }
    tmp := s.Item[s.Cnt-1]
    s.Cnt--
    return tmp,nil
}
栈在函数中的应用。

函数调用栈,操作系统会给每一个线程分配一块独立的内存空间,这块内存被组织成了“栈”这种结构。栈是用来存放临时变量的,每进入一个函数,就会将临时变量作为一个栈帧压入栈。当被调用函数执行完成之后,对应栈帧会被弹出。

func add(x,y int) int {
    var sum int
    sum = x+y
    return sum
}

func main() {
    var a   int = 1
    var ret int
    var res int

    ret = add(3,5)
    res = a + ret
    fmt.Println(res)
}
函数栈

关于栈相关的题目在leetcode上可以尝试 20,155,232,844,224,682,496

如 20 题 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
例如 “[][]{()[]}” true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses

利用栈来解决。

type Stack struct {
    item  []string
    cnt   int
}

func (s *Stack) Pop()  {  // 这个pop只弹出就可以了,不需要返回内容
    s.item[s.cnt-1] = ""
    if s.cnt > 0 {
        s.cnt--  // 指针偏移一下
    }
}

func (s *Stack) Push(str string)  {
    if s.cnt < 10 {
        s.item[s.cnt] = str
    } else {
        s.item = append(s.item,str)
    }
    s.cnt ++
}

func (s *Stack) InitStack() {
    s.item = make([]string,10)
    s.cnt = 0
}

func (s *Stack) GetTop() string {
    if s.cnt - 1 < 0 {
        return ""
    }
    return s.item[s.cnt-1]
}

func (s *Stack) IsEmpty() bool {
    return s.cnt == 0
}

func isValid(s string) bool {
    ss := &Stack{}
    ss.InitStack()

    for i := 0; i < len(s); i++{
        top := ss.GetTop()
        switch top {
        case "{":
            if string(s[i]) == "}" {   // 遇到一对 就弹出
                ss.Pop()
            } else {
                ss.Push(string(s[i]))  // 否则再压入栈中
            }
        case "(":
            if string(s[i]) == ")" {
                ss.Pop()
            }else {
                ss.Push(string(s[i]))
            }
        case "[":
            if string(s[i]) == "]" {
                ss.Pop()
            }else {
                ss.Push(string(s[i]))
            }
        default:
            ss.Push(string(s[i]))
        }

    }

    return ss.IsEmpty()
}

执行结果


相关文章

  • Java实现栈

    数组栈:压栈、出栈、返回栈顶元素 链式栈:压栈、出栈、返回栈顶元素

  • 数据结构之 栈

    栈结构 链式栈 一.栈结构体 1构建空栈 2栈置空 3判断栈空 4获取栈顶 5入栈 6出栈 7便利栈 二.链式栈 ...

  • 栈和队列

    1、栈 栈是一种先进先出的数据结构。栈顶进栈,栈顶出栈。 数据结构 栈的初始化 进栈 出栈 栈的最小值 2、队列 ...

  • 递归累加数组

    入栈 5入栈 4入栈 3入栈 2入栈 1出栈 [1 0]出栈 [2 1 0]出栈 [3 2 1 0]出栈 [4 3...

  • 栈的逻辑结构和存储结构

    main()进栈s(1)进栈s(0)进栈 s(0)出栈s(1)出栈main()出栈 顺序栈 一个数组 + 指向栈顶...

  • 单调栈 2020-06-12(未经允许,禁止转载)

    1.单调栈 指栈内元素保持单调性的栈结构,分为单调增栈(栈底到栈顶元素递增)和单调减栈(栈底到栈顶元素递减) 2....

  • 链栈的操作

    链栈的定义 链栈的操作 初始化 判断栈空 入栈 出栈

  • 函数调用栈平衡

    栈平衡 栈平衡:函数调用前后的栈顶指针指向的位置不变 内平栈 外平栈 内平栈: 指的是在函数调用返回之前使栈保持...

  • 栈的简单Java实现

    栈栈的特点是先进后出,出栈、入栈都是在栈顶操作。

  • 汇编学习-入栈和出栈

    栈有两个基本的操作:入栈和出栈。入栈就是将一个新的元素放到栈顶,出栈就是从栈顶取出一个元素。栈顶的元素总是最后入栈...

网友评论

      本文标题:

      本文链接:https://www.haomeiwen.com/subject/bjtdsctx.html