重学数据结构(二、栈)

简介: 重学数据结构(二、栈)

文章目录

1、栈的定义和特点

栈(Stack)又称堆栈, 是限制在表的一端进行插入和删除运算的线性表。

如果要拿一个东西对比,羽毛球筒比较合适。

image.png

栈遵循后进先出( Last-in-first-out,LIFO)的原则。

比如上面的羽毛球筒,只能将最顶端的羽毛球移出,也只能将新的羽毛球放到最顶端——这两种操作分别称作入栈( Push)出栈( Pop)。入栈和出栈的示意图如下:

image.png


最顶端的羽毛球叫栈顶栈顶 (top),最底端的羽毛球称为栈底 (bottom)

image.png

2、栈的基本操作

栈的基本操作除了入栈和出栈外, 还有栈的初始化、 栈空的判定, 以及取栈顶元素等。

根据这些操作,我们定义一个接口:

/**
 * @Author 三分恶
 * @Date 2020/8/26
 * @Description 栈接口
 */
public interface Stack {
    public int getSize();          //返回栈中元素数目
    public boolean isEmpty();      //判空
    public Object top();           //取栈顶元素但不删除
    public void push(Object element);      //入栈
    public Object pop();              //出栈
}

线性表有顺序和链式两种实现,栈同样有两种实现。

3、顺序栈

这里我们通过一个可扩容的数组来实现。

/**
 * @Author 三分恶
 * @Date 2020/8/26
 * @Description 顺序栈--数组实现
 */
public class ArrayStack implements Stack{
    private static  int defaultSize=15;   //默认容量
    private int size;                    //实际容量:实际存储元素个数
    private Object[] data;               //存放元素的数组
    /**
     * 无参构造方法:按默认容量构造元素数组
     */
    public ArrayStack() {
        data=new Object[defaultSize];
        size=0;
    }
    /**
     * 有参构造方法:指定元素数组容量
     * @param size
     */
    public ArrayStack(int size){
        data=new Object[size];
    }
    public int getSize() {
        return size;
    }
    public boolean isEmpty() {
        return size==0;
    }
    /**
     * 取栈顶元素:不删除栈顶元素
     * @return
     */
    public Object top() {
        if (isEmpty())
            throw new RuntimeException("栈空");
        size--;
        return data[size-1];
    }
    /**
     * 入栈
     * @param element
     */
    public void push(Object element) {
        //数组已满,扩容
         if (size==data.length){
             //扩容两倍的新数组
             Object [] newData=new Object[size<<1];
             //拷贝数组
             System.arraycopy(data,0,newData,0,size);
             data=newData;
         }
         //栈顶上插入新元素
         data[size]=element;
         size++;
    }
    /**
     * 出栈
     * @return
     */
    public Object pop() {
        if (isEmpty())
            throw new RuntimeException("栈空");
        Object top=data[size-1];
        data[size-1]=null;
        size--;
        return top;
    }
}

时间复杂度分析:

  • getSize():O(1)
  • isEmpty():O(1)
  • top():O(1)
  • push():平均O(1),最坏(扩容)O(n)
  • pop(): O(1)

3、链栈

链栈指的是链式存储结构实现的栈。在前面的学习中,我们已经完成了单向链表的实现,代码如下,具体说明可查看上一篇内容:

1_01.jpg1_02.jpg1_03.jpg1_04.jpg1_05.jpg1_06.jpg1_07.jpg

现在我们通过单向链表来实现链栈:

/**
 * @Author 三分恶
 * @Date 2020/8/26
 * @Description
 */
public class ListStack implements Stack{
    //单向链表
    private SinglyLinkedList list;
    /**
     * 构造函数:初始化单向链表
     */
    public ListStack(){
        list=new SinglyLinkedList();
    }
    /**
     * 获取栈的容量
     * @return
     */
    public int getSize() {
        return list.getSize();
    }
    public boolean isEmpty() {
        return list.getSize()==0;
    }
    /**
     * 取栈顶元素
     * @return
     */
    public Object top() {
        //取列表的尾节点
        return list.get(list.getSize()-1);
    }
    /**
     * 入栈
     * @param element
     */
    public void push(Object element) {
        //队列尾插入
       list.addTail(element);
    }
    /**
     * 出栈
     * @return
     */
    public Object pop() {
        int topIndex=list.getSize()-1;
        //列表为节点
        Object top=list.get(topIndex);
        //删除尾结点
        list.remove(topIndex);
        return top;
    }
}

时间复杂度分析:

  • getSize():O(1)
  • isEmpty():O(1)
  • top():O(1)
  • push():O(1)
  • pop(): O(1)

4、java中的栈

在Java中有一个java.util.Stack类,它实现了栈的结构。

它是Vector的子类,也自定义了一些作为栈的方法。

image.png

java.util.Stack类是Vector的子类,实际上并不建议使用它。

在Java中还有另外一个集合,可以作为栈使用,它就是LinkedList。LinkedList中实现了push、pop方法。具体可以查看LinkedList源码阅读笔记

源码地址:https://gitee.com/LaughterYoung/data-structure-learn.git


目录
相关文章
|
4天前
|
DataX
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
|
1月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
142 77
|
1月前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
38 7
|
1月前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
44 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
1月前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
46 9
|
3月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
99 5
|
3月前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
72 0
|
3月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
55 1
|
3月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
116 21
|
3月前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。

热门文章

最新文章