当前位置: 代码网 > it编程>编程语言>Java > Java数据结构之队列示例详解

Java数据结构之队列示例详解

2025年12月21日 Java 我要评论
一、队列队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表,一种先进先出的数据结构。队尾:允许插入的一端。队头:允许删除的一端。二、队列的模拟实现队列的底层可以是顺序表,可以是链表实现。2

一、队列

队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表,一种先进先出的数据结构。

队尾:允许插入的一端。

队头:允许删除的一端。

二、队列的模拟实现

队列的底层可以是顺序表,可以是链表实现。

2.1 队列的链式实现

在实现队列前我们先思考使用什么样的链表来实现?

由于栈的特性是先入先出,如果使用单链表和双向链表都可以,

只要在单链表标记一下尾节点就行,

但是因为java提供的是双向链表实现的,所以我们使用双向链表。

2.1.1 接口实现

实现的接口如下:

public class myqueue {
	//入队列
    public void offer(int val) {}
	//出队列
    public int poll() {}
    //获取队头元素 但是不删除
    public int peek() { }
    //判空
    public boolean isempty() { } 
    //获取队列元素个数
    public int size(){}      
}

2.1.2 内部类

跟双向链表的内部类实现差不多。

static class listnode{
        public int val;
        public listnode prev;
        public listnode next;

        public listnode(int val) {
            this.val = val;
        }
    }
    public listnode head;
    public listnode last;

2.1.3 入队列

实现思路:

  1. 先看队列是否为空,为空,头尾指向入队节点。
  2. 不为空尾节点的后继next指向入队节点,入队节点前驱prev指向尾节点,尾节点变为入队节点。
public void offer(int val){
	listnode cur = new listnode(val);
	if(isempty()){
		head = last = cur;
		return;
	}
	last.next = newnode;
    newnode.prev = last;
    last = newnode;
}

2.1.4 出队列

实现思路:

  1. 先判断队列是否为空,队列为空抛异常。
  2. 队列不为空,将头节点记录下来,头节点后一个节点前驱prev置为空,头节点变为后一个节点。
public int poll() throws nullpointerexception{
	try{
		if(isempty()){
			throw new nullpointerexception;
		}
	}catch(nullpointerexception e){
		 e.printstacktrace();
	}
	listnode cur = head;
	head.next.prev = null;
	head = head.next;
	return cur.val;
}

2.1.5 获取队头元素 但是不删除

实现思路:

  1. 先判断队列是否为空,队列为空抛异常。
  2. 队列不为空,返回头节点。
 public int peek() throws nullpointerexception{
	try{
		if(isempty()){
			throw new nullpointerexception;
		}
	}catch(nullpointerexception e){
		 e.printstacktrace();
	}
	return head.val;
}

2.1.6 判空

直接返回头是否为空就行。

public boolean isempty(){
	return head == null;
}

2.1.7 获取队列元素个数

直接循环遍历即可。

    public int size(){
    	listnode cur = head;
    	int size = 0;
		while(cur != null){
			cur = cur.next;
			size++;
		}
		return size;
	} 

2.2 队列的顺序实现(循环队列)

2.2.1 直接使用顺序表的缺陷

当我们直接使用顺序表来放数据时,我们将元素入队列放在数组尾,出队列时将数组前面元素出去后,会使前面浪费的空间越来越大。

基于此我们就用循环队列来实现,还是数组作为底层,但我们将其想象成一个圆。

2.2.2 接口实现

class mycircularqueue {
	//构造器,设置队列长度为 k
    public mycircularqueue(int k) {}
    // 向循环队列插入一个元素。如果成功插入则返回真。
    public boolean enqueue(int value) {}
    //从循环队列中删除一个元素。如果成功删除则返回真。
    public boolean dequeue() {}
    //从队首获取元素。如果队列为空,返回 -1 
    public int front() {}
    //获取队尾元素。如果队列为空,返回 -1 。
    public int rear() {}
    //检查循环队列是否为空。
    public boolean isempty() {}
    //检查循环队列是否已满。
    public boolean isfull() {}
};

2.2.3 成员变量

数组arr ,头下标front,尾节点下一个下标rear,数组长度size。

private int []arr;
private int front;
private int rear;
private int size;

2.2.4 构造器,设置队列长度为 k

因为我们使用的判空方法(下文讲)会造成一个空间的浪费,所以多申请一个空间。

public mycircularqueue(int k) {
        size = k+1;
        arr = new int[size];
        front = rear = 0;
    }

2.2.5 向循环队列插入一个元素 成功插入则返回真

实现思路:

  1. 判断队列是否已满,满了就返回false。
  2. 不满就在rear放。
  3. 因为是循环队列,所以rear的赋值要使用取余。
public boolean enqueue(int value) {
        if(isfull()){
            return false;
        }else{
            arr[rear] = value;
            rear = (rear + 1) % size;
            return true;
        }
    }

2.2.6 从循环队列中删除一个元素 成功删除则返回真

实现思路:

  1. 判断队列是否为空,空就返回false。
  2. 不空就直接将front指向下一个位置。
  3. 因为是循环队列,所以front的赋值要使用取余。
public boolean dequeue() {
        if(isempty()){
            return false;
        }else{
            front = (front + 1) % size;
            return true;
        }
    }

2.2.7 从队首获取元素。如果队列为空,返回 -1

实现思路:

  1. 先判断队列是否为空,为空返回-1。
  2. 不为空,返回front下标对应值。
public int front() {
        if(isempty()){
            return -1;
        }else{
            return arr[front];
        }
    }

2.2.8 获取队尾元素。如果队列为空,返回 -1

实现思路:

  1. 先判断队列是否为空,为空返回-1。
  2. 不为空,再判断rear是否为0,是0就返回数组最后一个元素。
  3. 不为0,就直接返回rear-1下标对应的元素。
public int rear() {
         if(isempty()){
            return -1;
        }else{
            if(rear == 0){
                return arr[size - 1];
            }else{
                return arr[rear - 1];
            }                    
        }
    }

2.2.9 检查循环队列是否为空

检查空根据循环队列的实现有两种方法:

  1. 使用usedsize记录队列元素个数,个数为0就是空。
  2. 空一个空间,如果front和rear相等那就是空。
public boolean isempty() {
        return rear == front;
    }

2.2.10 检查循环队列是否已满

检查满根据循环队列的实现有两种方法:

  1. 使用usedsize记录队列元素个数,个数和size相等就是满。
  2. 空一个空间,如果rear的下一个位置就是front那就是满。
public boolean isfull() {
        return front == (rear+1) % size;
    }

三、java中的queue

java中queue的底层是linkedlist实现的。

并且queue只是一个接口,必须new对象linkedlist才能使用。

3.1 实现的接口

实现的接口如下:

3.2 常用方法

常用方法如下:

四、队列练习

用队列实现栈

用栈实现队列

设计循环队列

到此这篇关于java数据结构之队列示例详解的文章就介绍到这了,更多相关java数据结构队列内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com