zoukankan      html  css  js  c++  java
  • 队列

    队列

    队列是用数组或链表实现的,遵循先进先出规则的一个有序列表

    使用数组模拟队列

    public class ArrayQueue<T> {
    
    	private Object[] arr;
    	private int front;
    	private int rear;
    	private int capacity;
    	
    	public ArrayQueue() {
    		this.capacity=10;
    		this.front=-1;
    		this.rear=-1;
    		this.arr=new Object[this.capacity];
    	}
    	
    	public ArrayQueue(int capacity) {
    		this.capacity=capacity;
    		this.front=-1;
    		this.rear=-1;
    		this.arr=new Object[this.capacity];
    	}
    	
    	public boolean add(T t) {
    		if(this.rear<this.capacity-1) {
    			this.arr[++rear]=t;
    			return true;
    		}
    		throw new RuntimeException("队列已满!");
    	}
    	
    	public T remove() {
    		if(this.rear==this.front) {
    			throw new RuntimeException("队列为空,不能出队列!");
    		}
    		return (T)this.arr[++front];
    	}
    	
    	public T poll() {
    		if(this.rear==this.front) {
    			return null;
    		}
    		return (T)this.arr[++front];
    	}
    	
    	public T peek() {
    		if(this.rear==this.front) {
    			return null;
    		}
    		return (T)this.arr[++front];
    	}
    	
    	
    	
    	@Override
    	public String toString() {
    		String str= "ArrayQueue [";
    		for(int i=front+1;i<=rear;i++) {
    			str+=this.arr[i]+" ";
    		}
    		return str+="]";
    	}
    
    	public static void main(String[] args) {
    		ArrayQueue<Integer> queue=new ArrayQueue<>(4);
    		queue.add(1);
    		queue.add(2);
    		queue.add(3);
    		queue.add(4);
    		System.out.println(queue);
    		
    		Integer remove1 = queue.remove();
    		System.out.println(remove1);
    		
    		Integer remove2 = queue.remove();
    		System.out.println(remove2);
    		
    		Integer remove3 = queue.remove();
    		System.out.println(remove3);
    		
    		Integer remove4 = queue.remove();
    		System.out.println(remove4);
    		
    		queue.add(5);
    		
    	}
    }
    
    输出:
    ArrayQueue [1 2 3 4 ]
    1
    2
    3
    4
    Exception in thread "main" java.lang.RuntimeException: 队列已满!
    

    分析:虽然队列中的元素已经全部出队,但是由于我们的队列是使用数组模拟的,而且每次入队的时候,头指定都后移,当我们入队次数增加,总有一时刻,头指针指向数组最大下标,尽管我们有出队,但是任然不能入队元素,我们可以使用数组模拟循环队列来解决这个问题

    使用数组模拟循环队列

    分析

    我们可以做这样一个约定,在数组中空一个位置,当(rear+1)%capacity==front来表示队满,当front==rear时表示队空

    这个时候,那么计算队列中元素个数公式为:size=(rear+capacity-front)%capacity

    public class CircleArrayQueue<T> {
    
    	private Object[] arr;
    	private int front;
    	private int rear;
    	private int capacity;
    	
    	public CircleArrayQueue() {
    		this.capacity=10;
    		this.front=0;
    		this.rear=0;
    		this.arr=new Object[this.capacity];
    	}
    	
    	public CircleArrayQueue(int capacity) {
    		this.capacity=capacity;
    		this.front=0;
    		this.rear=0;
    		this.arr=new Object[this.capacity];
    	}
    	
    	public boolean add(T t) {
    		if((rear+1)%capacity==front) {//队列已满
    			throw new RuntimeException("队列已满!");
    		}
    		//rear下标超出最大下标,那么取模
    		rear=(rear+1)%capacity;
    		this.arr[rear]=t;
    		return true;
    	}
    	
    	public T remove() {
    		if(this.rear==this.front) {
    			throw new RuntimeException("队列为空,不能出队列!");
    		}
    		return (T)this.arr[++front];
    	}
    	
    	public T poll() {
    		if(this.rear==this.front) {
    			return null;
    		}
    		return (T)this.arr[++front];
    	}
    	
    	public T peek() {
    		if(this.rear==this.front) {
    			return null;
    		}
    		return (T)this.arr[++front];
    	}
    	
    	public int size() {
    		return (rear+capacity-front)%capacity;
    	}
    	
    	@Override
    	public String toString() {
    		String str= "ArrayQueue [";
    		int total=size();
    		int index=front+1;
    		for(int i=0;i<total;i++) {
    			str+=arr[index]+" ";
    			index=(index+1)%capacity;
    		}
    		return str+="]";
    	}
    	
    	public static void main(String[] args) {
    		CircleArrayQueue<Integer> queue=new CircleArrayQueue<>(4);
    		//由于需要空一个,capacity为4也只能存放三个元素
    		queue.add(1);
    		queue.add(2);
    		queue.add(3);
    		System.out.println(queue);
    		
    		Integer remove = queue.remove();
    		System.out.println(remove);
    		
    		queue.add(4);
    		System.out.println(queue);
    	}
    }
    输出:
    ArrayQueue [1 2 3 ]
    1
    ArrayQueue [2 3 4 ]
    

    链队列

    使用节点来包装值,好处是使用链表可以不用考虑大小的问题,队列永远不可能满

    public class LinkedQueue<T> {
    
    	static class Node<T>{
    		T val;
    		Node next;
    		public Node(T val, Node next) {
    			super();
    			this.val = val;
    			this.next = next;
    		}
    		
    		public Node(T val) {
    			this.val=val;
    		}
    	}
    	
    	private int size;
    	private Node<T> front;
    	private Node<T> rear;
    	
    	public LinkedQueue() {
    		this.size=0;
    	}
    	
    	public void add(T t) {
    		Node<T> node=new Node<T>(t);
    		this.size++;
    		if(rear==null) {
    			rear=node;
    			front=node;
    		}
    		rear.next=node;
    		rear=node;
    	}
    	
    	public T remove() {
    		if(size<=0) {
    			throw new RuntimeException("队列为空,不能出队!");
    		}
    		size--;
    		Node<T> n=front;
    		if(size==0) {
    			front=null;
    			rear=null;
    			return n.val;
    		}
    		front=front.next;
    		return n.val;
    	}
    	
    	public T poll() {
    		if(size<=0) {
    			return null;
    		}
    		size--;
    		Node<T> n=front;
    		if(size==0) {
    			front=null;
    			rear=null;
    			return n.val;
    		}
    		front=front.next;
    		return n.val;
    	}
    	
    	public T peek() {
    		if(this.size<=0) {
    			return null;
    		}
    		return front.val;
    	}
    	
    	public int size() {
    		return size;
    	}
    	
    	@Override
    	public String toString() {
    		String str= "LinkedQueue [";
    		Node<T> n=front;
    		while(n!=null) {
    			str+=n.val+" ";
    			n=n.next;
    		}
    		str+="]";
    		return str;
    	}
    
    	public static void main(String[] args) {
    		LinkedQueue<Integer> queue =new LinkedQueue<>();
    		queue.add(1);
    		queue.add(2);
    		queue.add(3);
    		System.out.println(queue);
    		
    		Integer remove1 = queue.remove();
    		System.out.println(remove1);
    		
    		Integer remove2 = queue.remove();
    		System.out.println(remove2);
    		
    		Integer remove3 = queue.remove();
    		System.out.println(remove3);
    		
    		queue.remove();
    	}
    }
    
    输出:
    LinkedQueue [1 2 3 ]
    1
    2
    3
    Exception in thread "main" java.lang.RuntimeException: 队列为空,不能出队!
    
  • 相关阅读:
    为 ADO 程序员设计的 ADO.NET (转)
    MSN 历史纪录分页显示(XML + XSL + Javascript)
    python连接postgresql数据库
    centOS安装scikitlearn
    14. 页高速缓存 20100228 21:10 322人阅读 评论(0) 收藏
    18. 程序的执行 20100302 12:56 131人阅读 评论(0) 收藏
    ttt 20110118 11:49 71人阅读 评论(0) 收藏
    15. 访问文件 20100228 22:55 129人阅读 评论(0) 收藏
    17. 进程间通信 20100302 12:49 191人阅读 评论(0) 收藏
    19(终). 系统启动 20100302 13:00 191人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/moyuduo/p/12657160.html
Copyright © 2011-2022 走看看