带你整理面试过程中关于 Java中对于栈和队列的复习的相关知识点

Posted 南淮北安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带你整理面试过程中关于 Java中对于栈和队列的复习的相关知识点相关的知识,希望对你有一定的参考价值。

文章目录

一、栈及其Java实现

栈(Stack)又名堆栈,是允许在同一端进行插入和删除操作的特殊线性表。

其中,允许进行插入和删除操作的一端叫作栈顶(Top),另一端叫作栈底(Bottom),栈底固定,栈顶浮动。

栈中的元素个数为零时,该栈叫作空栈。插入一般叫作进栈(Push),删除叫作退栈(Pop)。

栈也叫作后进先出(FILO-First In Last Out)的线性表。具体的数据结构如图4-1所示。


要实现一个栈,需要先实现以下核心方法:

  • push():向栈中压入一个数据,先入栈的数据在最下边
  • pop():弹出栈顶数据,即移除栈顶数据。
  • peek():返回当前的栈顶数据。

(1)定义栈的数据结构

以上代码定义了一个Stack的类,用来存储栈的数据结构;定义了一个数组data,用来存储栈中的数据;定义了maxSize,表示栈的最大容量;定义了top,表示栈顶数据的指针;定义了两个栈的构造函数,在构造函数没有参数时默认构造一个大小为10的栈。

//定义泛型 E
public class OneStack<E> 
    private Object[] data = null;
    private int maxSize = 0;
    private int top = -1;
    //初始栈容量为10
    OneStack() 
        this.maxSize = 10;
        data = new Object[10];
        top = -1;
    

    OneStack(int initSize) 
        if (initSize >= 0) 
            this.maxSize = initSize;
            data = new Object[initSize];
            top = -1;
         else 
            throw new RuntimeException("初始化大小不能小于0:" + initSize);
        
    
    //入栈操作
    public boolean push(E e)
        if (top==maxSize-1)
            throw new RuntimeException("栈已满,无法将元素入栈!");
        else 
            data[++top]=e;
            return true;
        
    
    //出栈操作
    public E pop()
        if (top==-1)
            throw new RuntimeException("栈为空!");
        else 
            return (E) data[top--];
        
    
    //取栈顶指针
    public E peek()
        if (top==-1)
            throw new RuntimeException("栈为空!");
        else 
            return (E) data[top];
        
    

(2)数据入栈,向栈顶压入一个数据

	//入栈操作
    public boolean push(E e)
        if (top==maxSize-1)
            throw new RuntimeException("栈已满,无法将元素入栈!");
        else 
            data[++top]=e;
            return true;
        
    

以上代码定义了方法push()来向栈中压入数据,在数据入栈前首先判断栈是否满了,具体的判断依据为栈顶元素的指针位置等于栈的最大容量。注意,这里使用maxSize -1是因为栈顶元素的指针是从0开始计算的。在栈有可用空间时,使用data[++top]=e在栈顶(top位置)上方新压入一个元素并为top加1。

(3)数据出栈,从栈顶移除一个数据:

    //出栈操作
    public E pop()
        if (top==-1)
            throw new RuntimeException("栈为空!");
        else 
            return (E) data[top--];
        
    

以上代码定义了方法pop()来从栈顶移除一个数据,移除前先判断栈顶是否有数据,如果有,则通过data[top–]将栈顶数据移出并给top减1。

(4)数据查询

    //取栈顶指针
    public E peek()
        if (top==-1)
            throw new RuntimeException("栈为空!");
        else 
            return (E) data[top];
        
    

以上代码定义了方法peek()来取出栈顶的数据,在取出栈顶的数据前先判断栈顶的元素是否存在,如果存在,则直接返回栈顶元素(注意:这里没有对栈顶的元素进行删除),否则抛出异常。

二、队列及其Java实现

队列是一种只允许在表的前端进行删除操作且在表的后端进行插入操作的线性表。

其中,执行插入操作的端叫作队尾,执行删除操作的端叫作队头。没有元素的队列叫作空队列,在队列中插入一个队列元素叫作入队,从队列中删除一个队列元素叫作出队。

因为队列只允许在队头插入,在队尾删除,所以最早进入队列的元素将最先从队列中删除,所以队列又叫作先进先出(FIFO-first in first out)线性表。具体的数据结构如图4-2所示。

要实现一个队列,需要先实现以下核心方法:

  • add():向队列的尾部加入一个元素(入队),先入队列的元素在最前边。
  • poll():删除队列头部的元素(出队)。
  • peek():取出队列头部的元素。

(1)定义队列的数据结构:

public class OneQueue<E> 
    private Object[] data = null;
    //队列的容量
    private int maxSize = 0;
    //队列头,允许删除
    private int front;
    //队列尾,允许插入
    private int rear;

    //初始化容量为10
    OneQueue() 
        data = new Object[10];
        maxSize = 10;
        front = 0;
        rear = 0;
    

    //指定初始化容量
    OneQueue(int initSize) 
        if (initSize >= 0) 
            data = new Object[initSize];
            maxSize = initSize;
            front = rear = 0;
         else 
            throw new RuntimeException("初始化大小不能小于0:" + initSize);
        
    

    //入队
    public boolean add(E e) 
        if (rear == maxSize) 
            throw new RuntimeException("队列已满,无法插入新的元素");
         else 
            data[rear++] = e;
            return true;
        
    

    //出队
    public E poll() 
        if (front == 0) 
            throw new RuntimeException("空队列无法出队!");
        
        
            E value = (E) data[front];
            data[front++] = null;
            return value;
        
    
    //取对顶元素
    public E peek() 
        if (front == 0) 
            throw new RuntimeException("空队列无法读取!");
         else 
            return (E) data[front];
        
    

以上代码定义了一个名为Queue的队列数据结构,并定义了用于存储队列数据的data数组、队列头位置标记 front、队列尾位置标记 rear、队列的容量 maxSize。队列的默认长度为 10,在初始化时,front 的位置等于 rear 的位置,都为0;在有新的数据加入队列时,front的值加1。

(2)向队列插入数据:

  //入队
    public boolean add(E e) 
        if (rear == maxSize) 
            throw new RuntimeException("队列已满,无法插入新的元素");
         else 
            data[rear++] = e;
            return true;
        
    

以上代码定义了方法add()来向队列中插入数据,在插入前先判断队列是否满了,如果队列有空间,则通过data[rear++]=e向队列的尾部加入数据并将队尾的指针位置加1。

(3)取走队列中的数据:

    //出队
    public E poll() 
        if (front == 0) 
            throw new RuntimeException("空队列无法出队!");
        
        
            E value = (E) data[front];
            data[front++] = null;
            return value;
        
    

以上代码定义了方法poll()来取出队列头部的数据,并将队列头部的数据设置为null以释放队列头部的位置,最后返回队列头部的数据。

(4)队列数据查询:

    //取对顶元素
    public E peek() 
        if (front == 0) 
            throw new RuntimeException("空队列无法读取!");
         else 
            return (E) data[front];
        
    

以上代码定义了方法peek()来访问并返回队列头部的数据

以上是关于带你整理面试过程中关于 Java中对于栈和队列的复习的相关知识点的主要内容,如果未能解决你的问题,请参考以下文章

带你整理面试过程中关于消息队列(RabbitMQ/RocketMQ/Kafka)的相关知识点

带你整理面试过程中关于 Java 中的 异常分类及处理的相关知识

带你整理面试过程中关于Java 中多线程的创建方式的最全整理

带你整理面试过程中关于 Java 的内存模型 JMM(Java Memory Model)的相关知识

带你整理面试过程中关于多线程中的线程池的相关知识点

带你整理面试过程中关于Redis 中的字典及 rehash的相关知识点