队列的两种实现方式

一、数组实现队列

数组实现队列有很大的劣势,比如:它容易造成存储空间的浪费,不易扩张等等。
解决办法:
(1) 动态扩充数组:入队时,先要判断当前元素是否能添加到数组中,如果数组已经满了则扩充数组,出对时:将前面的元素取出,赋空值。
(2)移动元素位置:出队时,后面的元素向前移动位置 缺点:每次出队都需要移动位置
(3)构造环形队列:真难过很好解决浪费存储空间的诟病。
1. 先定义一个存储队列元素的数组,定义数组长度,头指针,尾指针,和数组存储数据的个数,并初始化。

//定义一个数组
	Object array[];
	
	//数组存储数据的个数
	private Integer size;
	
	//头指针
	private Integer head;
	//尾指针
	private Integer tail;
	
	//数组长度
	private Integer length = 10;
	
	//构造方法
	public ArrayMyQueue() {
		array = new Object[length];
		head = tail = size = 0; 
	}

2. 判断队列是否为空
当头指针等于尾指针时,队列为空,返回true.

//判断队列是否为空
	public boolean isEmple() {
		if(head == tail) {
			return true;
		}
		return false;
	}

3. 入队
先判断,当数组存储元素个数大于数组长度时,当前元素不能入队。
然后再判断,当队列为空的话,重置头尾指针,将新元素赋给队首,尾指针为1,数组存储元素个数自增。
不为空的话,直接将新元素赋给队尾,尾指针自增,数组存储元素自增。

//入队
	public boolean add(E dex) {
		//判断当前元素是否能加进去
		if(size >= length) {
			return false;
		}
		if(head == tail) {   //为空的话重置头尾指针
			head = 0;
			array[head] = dex;
			tail = 1;
			size++;
			return true;
		}else {
			array[tail] = dex;
			tail++;
			size++;
			return true;
		}
	}

4. 出队
先判断队列是否为空,如果为空则返回空值。
反之,直接将队首元素赋给一个新的变量,头指针自增,数组存储元素个数自减,组后返回这个新的变量。

//出队
	public E pop() {
		//判断队列是否为空,如果为空返回空值
		if(head == tail) {
			return null;
		}
		E e = (E) array[head];
		head = head+1;
		size--;
		return e;
	}

5. 测试

public static void main(String[] args) {
		ArrayMyQueue<Integer> s = new ArrayMyQueue<Integer>();
		s.add(1);
		s.add(2);
		s.add(3);
		s.add(4);
		s.add(5);
		System.out.println("队首元素为:"+s.pop());
		System.out.println("队首元素为:"+s.pop());
		System.out.println("队首元素为:"+s.pop());
	}

6. 运行截图:
在这里插入图片描述

二、链表实现队列的操作

1. 首先编写一个节点类

package Queue;

public class Node<E> {   //节点类
	//当前节点
	E data;
	//下一个节点
	Node<E> next;
	//构造方法
	public Node(E data) {
		this.data = data;
	}

}

2. 编写实现类MyQueue,首先定义两个私有的节点head和tail。并编写判断队列是否为空的isEmple方法。

//队首
	private Node<E> head = null;
	//队尾
	private Node<E> tail = null;
	
	//查看队列死否为空
	public boolean isEmple() {
		return head == null;
	}

3. 入队:
创建一个新节点,当队首队尾都为空时,将新节点赋给队首队尾。反之将新节点赋给队首的下一个节点,将该节点作为队尾。

//入队
	public void add(E dex) {
		//创建一个新节点
		Node<E> newNode = new Node<E>(dex);
		if(head == null && tail == null) {
			head = tail = newNode;
		}else {
			tail.next = newNode;
			tail = newNode;
		}
	}

4. 出队:
首先直接调用isEmple()方法判断队列是否为空,如果为空的话直接返回空即可。反之将队首节点的值赋给一个变量,将队首节点的后继节点赋给队首节点,最后返回该变量。

//出队
	public E pop() {
		//判断队列是否为空
		if(isEmple()) {
			return null;
		}
		E nex = head.data;
		head = head.next;
		return nex;
	}

5. 队列长度:
将队首节点赋给一个新节点,并应以一个int型的变量赋给一个空值,然后循环判断该新节点非空,变量自增,将新节点的后继节点赋给新节点。

//队列长度
	public int size() {
		Node<E> temp = head;
		int i = 0;
		while(temp != null) {
			i++;
			temp = temp.next;
		}
		return i;
	}

6. 测试:

public static void main(String[] args) {
		MyQueue<Integer> s = new MyQueue<Integer>();
		s.add(1);
		s.add(2);
		s.add(3);
		s.add(4);
		System.out.println("队首元素为:"+s.pop());
		System.out.println("队首元素为:"+s.pop());
		System.out.println("队首元素为:"+s.pop());
	}
	

7. 运行截图:
在这里插入图片描述

发布了17 篇原创文章 · 获赞 0 · 访问量 233

猜你喜欢

转载自blog.csdn.net/weixin_45646463/article/details/103695319