赞
踩
1.基于数组的实现
队列的基本概念就是先进先出,但是如果采用数组来实现就会出现每次执行一次dequeue会把数组里面的每个元素都会移动一次,移动n次的时间复杂度就是O(n^2),我们想要优化它的dequeue操作,可以定义两个变量来记录它的栈顶和栈尾来进行入队和出队操作
- /**
- * Created by upupgogogo on 2018/4/26.下午6:02
- */
- public class LoopQueue<E> implements Queue<E> {
-
- private E[] data; //容器
-
- private int size; //队列长度
-
- private int front; //栈顶位置
-
- private int tail; //栈尾位置
-
- public LoopQueue(int capacity){
- data = (E[]) new Object[capacity];
- size = 0;
- front = 0;
- tail = 0;
- }
-
- public LoopQueue(){
- this(10);
- }
-
- @Override
- public int getSize(){
- return this.size;
- }
-
- @Override
- public boolean isEmpty(){
- return size == 0;
- }
-
- @Override
- public void enqueue(E e){
- if (size == getCapacity() ){
- resize(getCapacity() * 2); // 扩容
- }
- data[tail] = e;
- tail = (tail + 1) % data.length; //这个是一个循坏的队列
- size++;
- }
-
- @Override
- public E dequeue(){
- if(isEmpty())
- throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
-
- E ret = data[front];
- data[front] = null;
- front = (front + 1) % data.length;
- size --;
- if(size == getCapacity() / 4 && getCapacity() / 2 != 0)
- resize(getCapacity() / 2);
- return ret;
- }
-
- @Override
- public E getFront(){
- if(isEmpty())
- throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
- E ret = data[front];
- return ret;
-
- }
-
- public int getCapacity(){
- return data.length ;
- }
-
-
- private void resize(int capacity) {
- E[] newData = (E[]) new Object[capacity];
- for (int i = 0; i < size; i++)
- newData[i] = data[(i+front) % data.length];
- data = newData;
- front = 0;
- tail = size;
-
- }
-
- @Override
- public String toString(){
-
- StringBuilder res = new StringBuilder();
- res.append(String.format("Queue: size = %d , capacity = %d\n", size, getCapacity()));
- res.append("front [");
- for (int i = 0; i < size; i++){
- res.append(data[(i+front) % data.length]);
- if (i != size - 1)
- res.append(", ");
- }
- res.append("] tail");
- return res.toString();
- }

2.基于链表的实现
链表本身会有一个头指针,它进行dequeue时时间复杂度是O(1),但是进行enqueue的操作却是O(n)级别的,我们可以设置一个tail变量来记录尾结点,这样enqueue操作也是O(1)级别的
- /**
- * Created by upupgogogo on 2018/5/9.下午7:43
- */
- public class LinkedListQueue<E> {
-
- private class Node{
- public E e;
- public Node next;
-
- public Node(E e, Node next){
- this.e = e;
- this.next = next;
- }
-
- public Node(E e){
- this(e, null);
- }
-
- public Node(){
- this(null, null);
- }
-
- @Override
- public String toString(){
- return e.toString();
- }
- }
-
- private Node head,tail;
- private int size;
-
- public LinkedListQueue() {
- this.head = null;
- this.size = 0;
- this.tail = null;
- }
-
- public int getSize(){
- return this.size;
- }
-
- boolean isEmpty(){
- return size == 0;
- }
-
- public void enqueue(E e){
- if (isEmpty()){ //如果队列是空的,那么设置tail和head都指向new Node(e)
- tail = new Node(e);
- head = tail;
- }
- else {
- tail.next = new Node(e);
- tail = tail.next;
- }
- size ++;
-
- }
- public E dequeue(){
- if (isEmpty()){
- throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
- }
- Node resNode = head;
- head = head.next;
- resNode.next = null;
- size --;
- return resNode.e;
- }
-
- public E getFront(){
- if (isEmpty()){
- throw new IllegalArgumentException("Cannot getFront from an empty queue.");
- }
- return head.e;
- }
-
- public String toString(){
- StringBuilder res = new StringBuilder();
- res.append("Queue: front ");
-
- Node cur = head;
- while(cur != null) {
- res.append(cur + "->");
- cur = cur.next;
- }
- res.append("NULL tail");
- return res.toString();
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。