• 一、什么是栈
    1. 定义:只允许在一端(栈顶)进行插入和删除操作的线性表。
    2. 特点:先进后出。

    图示:

    二、栈的应用
    1. 只要实际问题符合先进后出的特点,即可使用栈进行解决。
    2. 栈在计算机科学领域具有广泛的应用,例如,在编译和程序执行过程中,就需要利用栈进行语法检查、计算表达式的值、实现函数或过程的嵌套调用或递归调用。
    3. 在一般问题算法设计中的应用也十分广泛,特别是在穷举(遍历或搜索)满足问题部分要求求解的过程中往往需要记录某一阶段穷举的特例,以便无法找到所要结果时能退回去(回溯)重新继续穷举。

    三、栈的实现
    栈可使用数组或单向线性链表实现,下面分别是这两种实现方式的Go语言代码。
    1. 数组栈

    /**
    * 数组栈
    * author:JetWu
    * date:2020.02.03
     */
    package arrayStack
    
    import (
    	"errors"
    	"fmt"
    )
    
    /**
    * 数组栈结构
    **/
    type ArrayStack struct {
    	slice []int
    	head  int //栈顶位置:slice最后一个有效元素的索引位置
    }
    
    /**
    * 创建空栈
    **/
    func NewArrayStack() *ArrayStack {
    	return &ArrayStack{
    		slice: make([]int, 10),
    		head:  -1,
    	}
    }
    
    /**
    * 使用切片创建栈
    **/
    func MakeArrayStack(slice []int) *ArrayStack {
    	return &ArrayStack{
    		slice: slice,
    		head:  len(slice) - 1,
    	}
    }
    
    /**
    * 打印栈
    **/
    func (as *ArrayStack) Print() {
    	fmt.Println("count:")
    	fmt.Println(as.Count())
    	fmt.Println("members:")
    	for i := as.head; i >= 0; i-- {
    		fmt.Print(as.slice[i], " ")
    	}
    	fmt.Println()
    }
    
    /**
    * 判断栈是否为空
    **/
    func (as *ArrayStack) IsEmpty() bool {
    	return as.head == -1
    }
    
    /**
    * 栈长度
    **/
    func (as *ArrayStack) Count() int {
    	return as.head + 1
    }
    
    /**
    * 入栈
    **/
    func (as *ArrayStack) Push(data int) bool {
    	as.head++
    	if as.head+1 <= len(as.slice) {
    		as.slice[as.head] = data
    	} else {
    		as.slice = append(as.slice, data)
    	}
    	return true
    }
    
    /**
    * 出栈
    **/
    func (as *ArrayStack) Pop() (int, error) {
    	if as.head == -1 {
    		return 0, errors.New("栈为空")
    	}
    	data := as.slice[as.head]
    	as.head--
    	return data, nil
    }
    

    2. 链表栈

    /**
    * 链表栈
    * author:JetWu
    * date:2020.02.03
     */
    package listStack
    
    import (
    	"errors"
    	"fmt"
    )
    
    /**
    * 链表栈节点结构
    **/
    type node struct {
    	data int
    	next *node
    }
    
    /**
    * 链表栈结构
    **/
    type ListStack struct {
    	head *node //链表头部,不存储实际数据
    }
    
    /**
    * 创建空栈
    **/
    func NewListStack() *ListStack {
    	return &ListStack{
    		head: &node{next: nil},
    	}
    }
    
    /**
    * 使用切片创建栈
    **/
    func MakeListStack(slice []int) *ListStack {
    	ls := NewListStack()
    	for i := 0; i < len(slice); i++ {
    		ls.Push(slice[i])
    	}
    	return ls
    }
    
    /**
    * 打印栈
    **/
    func (ls *ListStack) Print() {
    	count := 0
    	ptr := ls.head.next
    	fmt.Println("members:")
    	for ptr != nil {
    		fmt.Print(ptr.data, " ")
    		count++
    		ptr = ptr.next
    	}
    	fmt.Println()
    	fmt.Println("count:")
    	fmt.Println(count)
    }
    
    /**
    * 判断栈是否为空
    **/
    func (ls *ListStack) IsEmpty() bool {
    	return ls.head.next == nil
    }
    
    /**
    * 栈长度
    **/
    func (ls *ListStack) Count() int {
    	count := 0
    	ptr := ls.head.next
    	for ptr != nil {
    		count++
    		ptr = ptr.next
    	}
    	return count
    }
    
    /**
    * 入栈
    **/
    func (ls *ListStack) Push(data int) bool {
    	nod := node{data: data, next: ls.head.next}
    	ls.head.next = &nod
    	return true
    }
    
    /**
    * 出栈
    **/
    func (ls *ListStack) Pop() (int, error) {
    	if ls.head.next == nil {
    		return 0, errors.New("栈为空")
    	}
    	data := ls.head.next.data
    	ls.head.next = ls.head.next.next
    	return data, nil
    }
    

    注:这里栈存储int类型数据,存储其他类型元素可依理类推。

  • 相关阅读:
    [手把手]VMware 16 pro 装 Windows11专业版并激活
    [HTML] 做个空壳网页练手(菜鸡的自我信息完善
    从零玩HTML的一天
    [总结]C++ 之 向量vector
    [递归专题打卡]2021 6.30-7.2
    初学Socket笔记
    对java是编译型语言还是解释型语言的讨论
    PHP CURL POST 请求设置 Content-Type (指定Content-Type)
    webpack 报错 [webpack-cli] Unable to load '@webpack-cli/serve' command
    Vue cli 创建项目模板 / npm run build 打包后资源引用问题
  • 原文地址:https://www.cnblogs.com/wujuntian/p/12263652.html
Copyright © 2020-2023  润新知