目录

1.栈的顺序存储实现

1.1结构体定义

1.2 初始化栈

1.3入栈

1.4出栈

1.5完整代码

1.6拓展-一个数组实现两个栈

2.栈的链式存储实现

2.1链栈的结构体定义

2.2链栈的初始化

2.3链栈的入栈

2.4链栈的出栈

2.5链栈实现的完整代码


栈(stack),是具有一定操作约束的线性表。其只能在一端(栈顶,Top)做插入、删除操作。

  • 插入数据:入栈(Push)
  • 删除数据:出栈(Pop)
  • 先入后出:Last In First Out(LIFO)

栈的抽象数据类型描述

数据对象集:一个有0或多个元素的线性表。

操作集:

  1. 生成空栈,其最大长度为MaxSize
  2. 判断栈是否已满
  3. 判断栈是否为空
  4. 将元素压入栈
  5. 将栈顶元素返回并删除

1.栈的顺序存储实现

栈的顺序存储结构体,通常由一个数组一个记录栈顶元素位置的变量组成。

1.1结构体定义

type Stack struct {MaxSize intTop     intarr     [10]int
}

1.2 初始化栈

func initStack() (stack *Stack) {stack = &Stack{MaxSize: 10,Top:     -1,arr:     [10]int{},}return stack
}

1.3入栈

func (s *Stack) push(v int) error {//判断栈是否满if s.MaxSize-1 == s.Top {return errors.New("栈已满,无法插入数据")}s.Top++          //栈顶+1s.arr[s.Top] = v //入栈return nil
}

1.4出栈

func (s *Stack) pop() (int, error) {//判断栈是否为空if s.Top == -1 {return 0, errors.New("error: 栈为空")}v := s.arr[s.Top] //出栈s.Top--           //栈顶-1return v, nil
}

1.5完整代码

package mainimport ("errors""fmt"
)type Stack struct {MaxSize intTop     intarr     [10]int
}func main() {//初始化一个栈stack1 := initStack()//验证空栈pop报错fmt.Println("---空栈pop报错---")_, err := stack1.pop()if err != nil {fmt.Println(err)}//入栈fmt.Println("---栈满push报错---")for i := 1; 1 <= 20; i++ {err := stack1.push(i)if err != nil {fmt.Println(err)break}}//出栈v, _ := stack1.pop()fmt.Println("---pop出栈---:", v)
}func initStack() (stack *Stack) {stack = &Stack{MaxSize: 10,Top:     -1,arr:     [10]int{},}return stack
}func (s *Stack) push(v int) error {//判断栈是否满if s.MaxSize-1 == s.Top {return errors.New("栈已满,无法插入数据")}s.Top++          //栈顶+1s.arr[s.Top] = v //入栈return nil
}func (s *Stack) pop() (int, error) {//判断栈是否为空if s.Top == -1 {return 0, errors.New("error: 栈为空")}v := s.arr[s.Top] //出栈s.Top--           //栈顶-1return v, nil
}

1.6拓展-一个数组实现两个栈

使用一个数组实现两个堆栈,要求最大地利用数组空间。使数组只要有空间,入栈操作就可以成功。

package mainimport ("errors""fmt"
)type Stack struct {Top1 intTop2 intarr  [10]int
}func main() {//初始化一个栈stack1 := initStack()fmt.Println(stack1.arr)//验证空栈pop报错fmt.Println("---空栈pop报错---")_, err := stack1.pop(1)if err != nil {fmt.Println(err)}_, err = stack1.pop(2)if err != nil {fmt.Println(err)}//入栈fmt.Println("---栈满push报错---")for i := 1; i <= 5; i++ {err := stack1.push(i, 1)if err != nil {fmt.Println(err)break}}for i := 1; i <= 6; i++ {err := stack1.push(i, 2)if err != nil {fmt.Println(err)break}}fmt.Println(stack1.arr)//出栈v, _ := stack1.pop(1)fmt.Println("---pop出栈---:", v)v, _ = stack1.pop(2)fmt.Println("---pop出栈---:", v)
}func initStack() (stack *Stack) {stack = &Stack{Top1: -1,Top2: 10,arr:  [10]int{},}return stack
}//通过tag区分插入哪个队列
func (s *Stack) push(v int, tag int) error {//判断栈是否满if s.Top2-s.Top1 == 1 {return errors.New("栈已满,无法插入数据")}if tag == 1 {s.Top1++          //栈A,栈顶+1s.arr[s.Top1] = v //入栈} else if tag == 2 {s.Top2--          //栈B,栈顶-1s.arr[s.Top2] = v //入栈} else {return errors.New("tag参数不合法, 需要传入1或2")}return nil
}func (s *Stack) pop(tag int) (int, error) {var v int//判断栈是否为空if tag == 1 {if s.Top1 == -1 {return 0, errors.New("error: 栈A为空")}v = s.arr[s.Top1] //出栈s.Top1--          //栈A,栈顶-1} else if tag == 2 {if s.Top2 == 10 {return 0, errors.New("error: 栈B为空")}v = s.arr[s.Top2] //出栈s.Top2++          //栈B,栈顶+1}return v, nil
}

2.栈的链式存储实现

链栈

2.1链栈的结构体定义

type LinkStack struct {data intnext *LinkStack
}

2.2链栈的初始化

func initLinkStack() (linkStack *LinkStack) {//初始化链栈,新建链栈头节点linkStack = &LinkStack{data: -1,next: nil,}return linkStack
}

2.3链栈的入栈

func (s *LinkStack) push(v int) {//链栈可先不考虑栈满,因为目前没有对栈做限制pushNode := &LinkStack{data: v,next: nil,}pushNode.next = s.next //入栈节点的next指向头节点的next节点s.next = pushNode      //头节点指向入栈节点
}

2.4链栈的出栈

func (s *LinkStack) pop() (int, error) {var v int//判断栈是否为空if s.next == nil {return 0, errors.New("error: 栈为空")}tmpTop := s.nextv = tmpTop.data //出栈,获取节点的元素值s.next = tmpTop.next //头节点指向原栈顶节点的下一个节点tmpTop.next = nil    //原栈顶节点指向nilreturn v, nil
}

2.5链栈实现的完整代码

package mainimport ("errors""fmt"
)type LinkStack struct {data intnext *LinkStack
}func main() {//初始化一个链栈fmt.Println("---初始化链栈---")linkStack1 := initLinkStack()//入栈fmt.Println("---入栈---")for i := 1; i <= 5; i++ {linkStack1.push(i)fmt.Printf("第%v次出栈, 值为:%v\n", i, i)}//出栈fmt.Println("---出栈---")for i := 1; i <= 6; i++ {v, err := linkStack1.pop()if err != nil {fmt.Println(err)break}fmt.Printf("第%v次出栈, 值为:%v\n", i, v)}
}func initLinkStack() (linkStack *LinkStack) {//初始化链栈,新建链栈头节点linkStack = &LinkStack{data: -1,next: nil,}return linkStack
}func (s *LinkStack) push(v int) {//链栈可先不考虑栈满,因为目前没有对栈做限制pushNode := &LinkStack{data: v,next: nil,}pushNode.next = s.next //入栈节点的next指向头节点的next节点s.next = pushNode      //头节点指向入栈节点
}func (s *LinkStack) pop() (int, error) {var v int//判断栈是否为空if s.next == nil {return 0, errors.New("error: 栈为空")}tmpTop := s.nextv = tmpTop.data //出栈,获取节点的元素值s.next = tmpTop.next //头节点指向原栈顶节点的下一个节点tmpTop.next = nil    //原栈顶节点指向nilreturn v, nil
}

GO语言-数据结构-栈相关推荐

  1. 11.0、C语言数据结构——栈

    11.0.C语言数据结构--栈 栈的定义:         栈是一种重要的线性结构,可以这样讲,栈是前面讲过的线性表的一种具体形式:         官方定义:栈(stack)是一个 后进先出(Las ...

  2. c语言特殊计算器设计报告,C语言数据结构栈计算器的实现课题设计报告书

    C语言数据结构栈计算器的实现课题设计报告书 (13页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分 目录1. 课程设计任务 12. 需求分析 ...

  3. C语言数据结构-栈的使用及实例

    本文主要讨论C语言数据结构的又一重要结构--栈 一.栈的理论知识 1. 定义和特点 定义:只允许在一端插入和删除的线性表:允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom). 特点 ...

  4. c语言栈中符号 的作用是什么,C语言数据结构----栈的应用(程序的符号匹配检测)...

    本节主要讲利用栈来实现一个程序中的成对出现的符号的检测,完成一个类似编译器的符号检测的功能,采用的是链式栈. 一.问题的提出以及解决方法 1.假定有下面一段程序: #include #include ...

  5. C语言-数据结构-栈(静态栈与动态栈)

    一.简介 在哔哩哔哩看视频学的,赫斌老师数据结构入门的内容-b站搜索:av6159200(P33),通过学习,能独立把赫斌老师教的敲出来,由于动态栈(链表阉割版)的功能很少,我并没有增加什么其它功能, ...

  6. [C语言数据结构]栈

    目录 1.栈的定义: 1.2栈的特性: 1.3栈的实现: 1.4代码: 1.4.1结构的声明: 1.4.2栈的初始化: 代码: 1.4.3入栈: 代码: 1.4.4出栈 void StackPop(S ...

  7. C语言 数据结构 栈的数组实现 realloc函数

    主题:栈的数组实现 功能:分别栈的入栈.弹栈.打印操作 提示:运行程序自动进入入栈操作,退出入栈,数组3个ctrl z,然后进入出栈操作,输入非n的任意char字符,继续出栈.输入n结束出栈,整个程序 ...

  8. C语言 数据结构 栈(用链表实现)

    疑惑 为什么栈要分两个结构体来创建,而链表只需要一个? 能不能只用一个结构体创建一个栈? 代码 用函数实现了压栈,弹栈,打印栈的操作 #include<stdio.h> #include& ...

  9. C语言 数据结构 栈的应用(括号匹配)

    #include<stdio.h> #include<stdlib.h> #define MaxSize 10 #define true 1 #define false 0 t ...

最新文章

  1. Sphinx+gitee+Read the Docs搭建在线文档系统
  2. 十七、字符类 GPIOS
  3. java label覆盖_java – 将JLabel置于JLabel之上,其中包含图像
  4. RBAC 权限设计(转载)
  5. 【tool】kali连接rdp远程桌面
  6. 什么是条件组合覆盖_什么是综合评价?高中生报名有哪些好处?
  7. 心理学专业学要学计算机吗,心理学专业学什么 都有哪些课程
  8. 「程序猿 DD」星球活动第一期正式开启!
  9. 【服务器数据恢复】IBM某型号服务器RAID5磁盘阵列数据恢复案例
  10. 苹果app退款_苹果app退款流程:App Store应用如何申请iOS退款教程
  11. typechoSEO站点收录插件推荐
  12. DatePicker时间格式化年月日
  13. Incorrect string value: ‘\xE9\xBB\x84\xE8\x93\x89‘ for column ‘name‘ at row 1 MySQL 5.7解决方案
  14. 基于Python的多时相数据合成
  15. python大数据课程培训大纲
  16. 新版12306信息服务器,新版12306初体验来了!
  17. uniapp 区分环境运行、打包
  18. matebook13linux双系统,华为MateBook 13笔记本装win10系统及BIOS设置的方法
  19. 程序员小灰2020年整理
  20. element table v-for动态隐藏列

热门文章

  1. 爪哇国新游记之二十一----快算24
  2. 网络爬虫——中国大学排名数据抓取
  3. 大学生web前端期末大作业实例代码 (1500套,建议收藏) HTML+CSS+JS
  4. python的lambda函数妙用
  5. 2022泰迪杯数据分析技能赛B题方案及赛后总结:银行客户忠诚度分析
  6. c语言写红绿灯程序,51单片机用C语言实现交通灯(红绿灯)源程序
  7. html5批量修改本地文件名,文件名批量更名技巧;将文件夹名添加到文件名上-批量修改文件名...
  8. 测试ip 或者 ip+端口 是否畅通
  9. 绵阳南山中学计算机老师邱浩,还原“博士论文走红”的中科院博士:学成还乡衣着朴素...
  10. srs之ingest