数据结构笔记--栈的总结及java数组实现简单栈结构

简介: 杂谈"栈"结构:     栈(Stack)是一种插入删除操作都只能在一个位置上进表,这个位置位于表的末端,叫做栈顶(Top).   对栈的基本操作有push和pop,表示进栈和出栈.也就相当于插入和删除操作.

杂谈"栈"结构:  

  栈(Stack)是一种插入删除操作都只能在一个位置上进表,这个位置位于表的末端,叫做栈顶(Top).

  对栈的基本操作有push和pop,表示进栈和出栈.也就相当于插入和删除操作.

  栈结构又叫做LIFO(后进先出)表.归根结底是一个表结构,因此任何能够实现表结构的方法都能实现栈.

  在java语言中,ArrayList和LinkedList都支持栈操作,栈操作都是常数时间的操作,栈的实现方式一般有两种,一种是使用顺序存储的方式,即使用数组来实现,用ArrayList可以轻易实现栈结构,也可以自己使用数组来实现,一会下面我就用数组来实现栈,第二种是使用链式存储实现,即可以使用LinkedList来实现.

使用数组实现顺序栈:

  使用arrayList和linkedList实现栈比较简单,毕竟本身他们就是封装好的功能,接下来我用数组来实现一个栈结构:

MyStack:

package com.wang.list;

import java.util.Arrays;

public class MyStack<T> {

    //使用数组实现这个栈结构
    private T[] dataArr;
    //当前元素的个数
    private int theSize;
    //栈的容量
    private static final int DEFAULT_CAPACITY=10;
    
    public MyStack(){
        clear();
        
    }
    //初始化数组,默认大小10,元素个数theSize初始化为o
    private void clear(){
        theSize=0;
        ensureCapacity(DEFAULT_CAPACITY);
    }
    
    //栈元素容量
    public int size(){
        return theSize;
    }
    
    private void ensureCapacity(int newCapacity){
        if(newCapacity<theSize){
            return;
        }
        T[] oldArr=dataArr;
        dataArr=(T[])new Object[newCapacity];
        for(int i=0;i<size();i++){
            dataArr[i]=oldArr[i];
        }
        
    }
    //入栈
    public void push(T value){
        if(dataArr.length==size()){
            ensureCapacity(size()*2);
        }
        dataArr[theSize++]=value;
    }
    //栈是否为空
    public boolean isEmpty(){
        return size()==0;
    }
    //出栈
    public T pop(){
        if(isEmpty()){
            return null;
        }
        T theValue=dataArr[theSize-1];
        dataArr[--theSize]=null;
        return theValue;
        
    }
    //返回栈尾元素
    public T peek(){
        if(isEmpty()){
            return null;
        }
        T theValue=dataArr[theSize-1];
        return theValue;
    } 
}

使用Node()辅助类实现链式栈:

 

package com.wang.list;

public class MyStack1<T> {

    
    private class Node{
        
         T data;
        Node next;
        
        
        public Node(T data,Node next){
            
            this.data=data;
            this.next=next;
        }
    }
    
    //保存元素个数
    private int theSize;
    
    //保存栈顶元素
    private Node top;
    
    public MyStack1(){
        top=null;
    }
    
    public MyStack1(T value){
        top=new Node(value,null);
    }
    
    public void push(T value){
        top=new Node(value,top);
        theSize++;
        
    }
    
    public T pop(){
        Node old=top;
        top=top.next;
        old.next=null;
        theSize--;
        return old.data;
        
    }
    
    public T peek(){
        return top.data;
        
    }
    public int size(){
        return theSize;
    }
    
    public boolean isEmpty(){
        return size()==0;
    }
}

 

 

 

栈的应用:

  进制转换:

    比如将十进制下的某个数转换为二进制中的某个数,则可以对该数进行除2取余操作,然后将余数压栈,之后再将所有的数出栈,即是所对应的二进制数,这其实是栈对于逆序操作的一个实例.

  平衡符号:

    检查那些成对出现的符号是否匹配,比如(),[],{}等

    实现过程大概如下:

      做一个空栈,读入字符直到文件末尾.如果字符是一个开放符号(比如"{}"中的"{"),则将其推入栈中.如果字符是一个封闭符号(比如"{}"中的"}"),则判断栈是否为空,为空则报错.不为空,则将栈顶元素弹出,判断弹出元素是否是其对应的开放符号,不是则报错,在文件结尾,如果栈非空,就报错.

  后缀表达式:

    不知道何为后缀表达式,请自行百度,后缀表达式的记法又称为逆波兰式,它的求值过程恰好就是从左到右的过程,可以使用一个栈,当见到一个数时就入栈,当遇到一个一个运算符时,就从栈中弹出两个数进行计算,再将所得结果入栈.最后的到的数就是计算结果.

  用于方法调用:

    存在方法调用时,比如在一个方法中调用了另一个方法,这时候需要把当前方法一些重要信息记录并保存下来,保存到一个栈中,然后再跳到新方法中去执行,当方法返回的时候,去查看栈顶的那个保存信息(栈帧),然后进行复原,事实上这是在计算机系统中一个非常重要的应用,上面的全部工作都可以用一个栈来实现.事实上,在实现递归的每一种程序语言都是这么干的,所存储的信息叫做活动记录,或者说栈帧.这个细说,比较复杂,想深入了解,自己百度吧.

 

相关文章
|
4天前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
114 75
|
4天前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
25 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
4天前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
28 9
|
4天前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
23 7
|
30天前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
45 5
|
1月前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
1月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
1月前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
63 5
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
79 5
|
1月前
|
Java 数据库连接 编译器
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
62 0