数据结构——Java实现栈和队列

这篇具有很好参考价值的文章主要介绍了数据结构——Java实现栈和队列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、栈 Stack

1.特点

(1)栈是一种线性数据结构

(2)规定只能从栈顶添加元素,从栈顶取出元素

(3)是一种先进后出的数据结构(Last First Out)LIFO

2.具体实现

Java中可以直接调用方法来实现栈

数据结构——Java实现栈和队列,数据结构,java,开发语言

如何自己写代码来实现栈呢?

先定义一个接口,方便后边进行调用

package com.algo.lesson.lesson02.stack;

public interface Stack_I<T> {
    //入栈
    void push(T ele);
    //出栈
    T pop();
    //查看栈顶元素
    T peek();
    //判断是否为空
    boolean isEmpty();
    //后去栈中元素
    int getSize();
}

接下来来实现栈的方法,调用接口,完善方法:

package com.algo.lesson.lesson02.stack;

import com.algo.lesson.lesson01.MyArr;

//以数组作为栈顶的底层数据结构
public class ArrStack<T> implements Stack_I<T> {

    private MyArr<T>data;

    int size;

    public ArrStack() {
        this.data=new MyArr<>(100);
        this.size=0;
    }

    @Override
    public void push(T ele) {
        //在数组尾部添加元素
        this.data.add(ele);
        this.size++;
    }

    @Override
    public T pop() {
        if(isEmpty()){
            return null;
        }
        this.size--;
        return this.data.removeBFromLast();
    }

    @Override
    public T peek() {
        return this.data.getLastValue();
    }

    @Override
    public boolean isEmpty() {
        return this.size==0;
    }

    @Override
    public int getSize() {
        return this.size;
    }
}

以上就是方法的代码,接下来,写个main函数来调用,检查方法是否正确

package com.algo.lesson.lesson02.stack;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class StackTest<T> {
    public void test(Stack_I<T>stack, List<T> list){
        //开始时间
        long startTime=System.nanoTime();

        for(int i=0;i<list.size();i++){
            stack.push(list.get(i));
        }
        System.out.println(stack.getSize());
        while(!stack.isEmpty()){
            T ele=stack.pop();
            System.out.println(ele+"  ");
        }

        //结束时间
        long endTime=System.nanoTime();
        System.out.println("总耗时:"+(endTime-startTime)/100000000.0);
    }

    public static void main(String[] args) {
        StackTest<Integer>stackTest=new StackTest<>();
        Stack_I<Integer>stack=new ArrStack<>();
        List<Integer>list=new ArrayList<>();
        Random random=new Random();
        for(int i=0;i<100;i++){
            int val= random.nextInt(1000);
            list.add(val);
        }
        stackTest.test(stack,list);
    }
}

注:其中long startTime=System.nanoTime();方法是获取一个时间(单位毫秒)

在程序运行前和运行后个添加一个,最后将两个时间相减,得到程序运行时间。

数据结构——Java实现栈和队列,数据结构,java,开发语言

3.时间复杂度分析

数据结构——Java实现栈和队列,数据结构,java,开发语言

二、队列

1.特点

(1)队列也是一种线性数据结构

(2)只能从一端添加元素,另一端取出元素

(3)是一种先进先出的数据结构(FIFO——fist in fist out )

2.具体实现

Java中也可以直接调用队列的方法:

数据结构——Java实现栈和队列,数据结构,java,开发语言

自己的实现:

接口:

package com.algo.lesson.lesson02.queue;

public interface Queue_I<T> {
    void offer(T ele);//入队
    T poll();//出队
    T peek();//查找队首元素
    int getSize();
    boolean isEmpty();


}

方法代码:

package com.algo.lesson.lesson02.queue;

import com.algo.lesson.lesson01.MyArr;

public class ArrQueue<T>implements Queue_I<T> {

    private MyArr<T>data;

/*
    private int size;//队列中元素的个数
*/

    public ArrQueue(){
        this.data=new MyArr<>(50);
    }

    @Override
    public void offer(T ele) {
        this.data.add(ele);
    }

    @Override
    public T poll() {
        if(isEmpty()){
            return null;
        }
        return this.data.removeByIndex(0);
    }

    @Override
    public T peek() {
        if(isEmpty()){
            return null;
        }
        return this.data.getValueByIndex(0);
    }

    @Override
    public int getSize() {
        return this.data.getSize();
    }

    @Override
    public boolean isEmpty() {
        return this.data.isEmpty();
    }
}

3.出现的问题

入队列时间复杂度为O(n),因为在出队时,元素要前移,会出现假溢出的情况。

所以就出现了循环队列来解决这个问题

循环队列:

front记录队首,tail记录队尾,队尾达到容积时,返回到队头,将空位置补上,可以继续存储数据。

package com.algo.lesson.lesson02.queue;

import java.util.Random;

/*
基于Java中的数组进行二次封装,制作一个可变数组
 */
//泛型:就是类型作为参数
public class LoopArr<T> {
    private T[] data;//保存数据

    private int size;//数组中实际存放元素的个数

    private int front;//队首

    private int tail;//队尾

    int capacity;//容积

    //构造函数
    public LoopArr(int capacity) {
        if (capacity <= 0) {
            this.capacity = 11;
        } else {
            this.capacity = capacity + 1;
        }
        this.size = 0;
        this.front = this.tail = 0;
        this.data = (T[]) (new Object[this.capacity]);
    }

    //获取数组中实际存放元素的个数
    public int getSize() {
        return this.size;
    }

    //获取数组的容积
    public int getCapacity() {
        return this.capacity;
    }

    //判断数组是否为空
    public boolean isEmpty() {
        return this.front == this.tail;
    }

    //向数组中添加元素(尾部)
    public void add(T item) {
        //判断数组是否满
        if ((this.tail + 1) % this.capacity == this.front) {
            //扩容
            resize((this.capacity-1)*2+1);
        }
        //从index位置开始元素需要进行后移
        this.data[this.tail] = item;
        this.tail = (this.tail + 1) % this.capacity;
        //更新this.size
        this.size++;
    }

    private void resize(int newCapacity) {
        System.out.println("resize:" + newCapacity);
        T[] newData = (T[]) (new Object[newCapacity]);
        //将原数组驾到新数组里

        for (int i = 0; i < this.size; i++) {
            newData[i] = this.data[(this.front+i)%this.capacity];
        }
        //改变容器
        this.data = newData;
        this.capacity = newCapacity;
        //将this.front置零
        this.front=0;
        this.tail=this.size;
    }

    //获取指定位置的值
    public T getValueByIndex() {
        if(isEmpty()){
            return null;
        }
        return this.data[this.front];
    }

    //移除队首元素
    public T remove() {
        if (isEmpty()) {
            return null;
        }
        //删除操作的核心
        /*
        1.找到删除的位置
        2.删除位置之后的元素要前移 arr[j-1]=arr[j]
         */
        T delValue = this.data[this.front];
        this.front = (this.front + 1) % this.capacity;
        this.size--;
        //判断是否缩容
        if (this.size < this.capacity / 4 && this.capacity / 2 > 0) {
            resize((this.capacity-1) / 2 +1);
        }
        return delValue;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("[");
        for (int i = 0; i < this.size; i++) {
            sb.append(this.data[i]);
            if (i != this.size - 1) {
                sb.append(",");
            }
        }
        sb.append("]");
        return sb.toString();
    }
}
package com.algo.lesson.lesson02.queue;

public class LoopQueue<T> implements Queue_I<T>{

    private LoopArr<T>data;//容器

    public LoopQueue(){
        this.data=new LoopArr<>(100);
    }




    @Override
    public void offer(T ele) {
        this.data.add(ele);
    }

    @Override
    public T poll() {
        return this.data.remove();
    }

    @Override
    public T peek() {
        return this.data.getValueByIndex();
    }

    @Override
    public int getSize() {
        return this.data.getSize();
    }

    @Override
    public boolean isEmpty() {
        return this.data.isEmpty();
    }
}

4.循环队列的复杂度分析

数据结构——Java实现栈和队列,数据结构,java,开发语言

三、栈和队列的互相实现

既然我们了解了栈和队列,知道了这两种数据结构十分相似,也就可以大胆假设以下,可不可以相互实现,不是用上面所写的以数组为底层,而是相互为底层存储。

1.用栈来实现队列

import java.util.Stack;

class MyQueue {
    private Stack<Integer> A;
    private Stack<Integer> B;

    public MyQueue() {
        A = new Stack<>();
        B = new Stack<>();
    }

    public void push(int x) {
        while (!B.isEmpty()) {
            A.push(B.pop());
        }
        A.push(x);
        while (!A.isEmpty()) {
            B.push(A.pop());
        }
    }

    public int pop() {
        return B.pop();
    }

    public int peek() {
        return B.peek();
    }

    public boolean empty() {
        return B.isEmpty();
    }
}

2.用队列实现栈

import java.util.LinkedList;
import java.util.Queue;

class MyStack {
    private Queue<Integer> queue1;
    private Queue<Integer> queue2;

    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }

    public void push(int x) {
        queue2.add(x);
        while (!queue1.isEmpty()) {
            queue2.add(queue1.remove());
        }
        Queue<Integer> temp = queue1;
        queue1 = queue2;
        queue2 = temp;
    }

    public int pop() {
        return queue1.remove();
    }

    public int top() {
        return queue1.peek();
    }

    public boolean empty() {
        return queue1.isEmpty();
    }
}

这就是这两种数据结构相互实现的代码

在LeetCode中也有相对应的题目:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台(栈实现队列)

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台(队列实现栈)文章来源地址https://www.toymoban.com/news/detail-807662.html

到了这里,关于数据结构——Java实现栈和队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • c++实现数据结构栈和队列

    1、栈 头文件 源文件 主函数 2、循环队列 头文件 源文件 主函数 3、思维导图

    2024年02月08日
    浏览(39)
  • 数据结构基础5:栈和队列的实现。

    1.基本概念 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈:栈

    2024年02月13日
    浏览(39)
  • 【数据结构】栈和队列的模拟实现(两个方式实现)

    💓作者简介: 加油,旭杏,目前大二,正在学习 C++ , 数据结构 等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏👀 🚚代码仓库:旭日东升 1👀 🌹欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖        这一篇博客将学习栈和队列的相关知识, 栈

    2024年02月05日
    浏览(45)
  • 【数据结构和算法】---栈和队列的互相实现

    具体题目可以参考 LeetCode 232. 用栈实现队列 首先要想到的是,队列是一种 先进先出 的结构,而栈是一种 先进后出 的结构。依此 我们可以定义两个栈结构来模拟先进先出 ,既然要定义两个栈,那么为了方便调用,我们可以将这两个栈结构定义在一个结构体中,如下: 实现

    2024年02月03日
    浏览(42)
  • 数据结构初阶(用C语言实现简单数据结构)--栈和队列

    ✨✨欢迎来到T_X_Parallel的博客!!       🛰️博客主页:T_X_Parallel       🛰️专栏 : 数据结构初阶       🛰️欢迎关注:👍点赞🙌收藏✍️留言 这小猫真好看 言归正传,通过上篇有关顺序表和链表的博客,可以了解到线性表的一些大致特征,这篇博

    2024年02月08日
    浏览(42)
  • 数据结构上机实验——栈和队列的实现、栈和队列的应用、进制转换、约瑟夫环问题

      1.利用栈的基本操作实现将任意一个十进制整数转化为R进制整数。   2.利用循环队列实现.约瑟夫环问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到k的那个人出圈;他的下一个人又从1开始报数,数到k的那个人出圈;依

    2024年02月08日
    浏览(42)
  • 数据结构入门(C语言版)栈和队列之队列的介绍及实现

    什么是队列呢?我们先看下面的图: 我们可以理解成高速公路上的隧道,根据这个图的描述 我们把需入队的元素看作一辆车,把队列看作隧道,由此我们可以看出 队列的特点是 只允许从一端进入,从另一端离开。 队列就是只允许在一端进行插入数据操作,在另一端进行删

    2023年04月15日
    浏览(43)
  • 数据结构进阶篇 之 【栈和队列】的实现讲解(附完整实现代码)

    书读一边家里见 书读三遍大专见 书读百遍清北见 书读零遍感谢大哥的穿云箭🚀 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀– 概念

    2024年04月09日
    浏览(44)
  • 【数据结构】带你深入栈和队列,轻松实现各种接口功能

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello,米娜桑们,这里是君兮_,我们继续来学习初阶数据结构的内容,今天我们要讲的是栈与队列内容中队列部分的内容 好了,废话不多说,开始今天的学习吧! — 队列:只允许在一端进行插入数据操作,在另一端进行

    2024年02月13日
    浏览(50)
  • 【数据结构】带你图文结合深入栈和队列,并具体分步实现

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello,米娜桑们,这里是君兮_,我们继续来学习初阶数据结构的内容,今天我们要讲的是栈与队列部分的内容,这篇博客先讲栈,队列我们放到下次再讲 好了,废话不多说,开始今天的学习吧! — 栈:一种特殊的线性表

    2024年02月13日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包