1.队列的链式存储实现
队列接口:
package edu.njupt.zhb; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: [email protected] *2014-3-12 Nanjing,njupt,China */ public interface MyQueue { public void add(Object object);//从队列尾部加入一个元素 public Object remove();//出列,返回队列头部的值,并将其删除 public int getSize();//获取队列的大小 public Object peek();//偷看队列的前端元素,但是不出列 public boolean isEmpty(); }
/* * $filename: MyLinkedQueue.java,v $ * $Date: 2014-3-12 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ package edu.njupt.zhb; import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: [email protected] *2014-3-12 Nanjing,njupt,China */ /** * 队列的链式实现 */ public class MyLinkedQueue implements MyQueue{ public class Node{ Node next; Object data; } private Node front;//前面的指针 private Node rear;//后面的指针 private int size; public MyLinkedQueue(){ front=new Node(); front.next=null; rear=new Node(); rear.next=null; size=0; } /** * 入列,从尾部添加元素 */ @Override public void add(Object object) { // TODO Auto-generated method stub Node node = new Node(); node.data=object; if(size==0){//如果是空的 front.next=node; rear.next=node; size++; return; } rear.next.next=node;//将尾节点指向新增节点 rear.next=node;//将rear指针指向新增节点 size++; } /** * 出列,从头部取出元素,并删除 */ @Override public Object remove() { // TODO Auto-generated method stub if(front.next!=null){ Object object=front.next.data;//取出当前队列的头元素 front.next=front.next.next;//删除第一个元素 size--; return object; } return null; } @Override public int getSize() { // TODO Auto-generated method stub return size; } @Override public Object peek() { // TODO Auto-generated method stub return front.next.data; } @Override public boolean isEmpty() { // TODO Auto-generated method stub return size==0; } public static void main(String[] args) { MyQueue queue = new MyLinkedQueue(); for(int i=0;i<20;i++){ queue.add("str"+i); } while(!queue.isEmpty()){ Object object=queue.remove(); System.out.println((String)object); } } }
/* * $filename: MyArrayQueue.java,v $ * $Date: 2014-3-12 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ package edu.njupt.zhb; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: [email protected] *2014-3-12 Nanjing,njupt,China */ public class MyArrayQueue implements MyQueue { private int size; private int front; private int rear; final int INIT_LEN=10;//初始化长度 final int INCREAMENT_LEN=10;//长度增量大小 Object []objects;//用数组保存队列中的元素 public MyArrayQueue(){ size=0; front=0; rear=-1; objects = new Object[INIT_LEN]; } @Override public void add(Object object) { // TODO Auto-generated method stub if(size+1==objects.length){//扩充数组 Object []temp = new Object[objects.length+INCREAMENT_LEN]; for(int i=0;i<objects.length;i++){ temp[i]=objects[i]; } objects=temp; } objects[++rear]=object;//将元素添加在队列的尾部 size++; } @Override public Object remove() { // TODO Auto-generated method stub if(size==0){ return null; } Object object = objects[front];//取出队列的头元素 for(int i=0;i<objects.length-1;i++){//通过平移,删除已取出的元素 objects[i]=objects[i+1]; } size--; return object; } @Override public int getSize() { // TODO Auto-generated method stub return size; } @Override public Object peek() { // TODO Auto-generated method stub if(size==0){ return null; } Object object = objects[front];//取出队列的头元素 return object; } @Override public boolean isEmpty() { // TODO Auto-generated method stub return size==0; } public static void main(String[] args) { MyQueue queue = new MyArrayQueue(); for(int i=0;i<20;i++){ queue.add("str"+i); } while(!queue.isEmpty()){ Object object=queue.remove(); System.out.println((String)object); } } }
原因:主要是解决队列的“假溢出”问题。其实上面的顺序实现方式已经有效避免了假溢出(通过平移的方式)。下面来看一下循环队列吧。
/* * $filename: MyArrayCircularQueue.java,v $ * $Date: 2014-3-12 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ package edu.njupt.zhb; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: [email protected] *2014-3-12 Nanjing,njupt,China */ /** *实现循环队列操作: (1)为使入队和出队实现循环,可以利用取余运算符% (2)队头指针进一:front=(front+1) % maxSize (3)队尾指针进一:rear=(rear+1) % maxSize (4)空队列:当front==rear 时为空队列 (5)满队列:当(rear+1) % maxSize ==front时为满队列。满队列时实际仍有一个元素的空间未使用。 */ public class MyArrayCircularQueue implements MyQueue { private int front; private int rear; private final int maxSize = 10; private Object []objects; private int size; public MyArrayCircularQueue(){ front=rear=0; size=0; objects=new Object[maxSize]; } @Override public void add(Object object) { // TODO Auto-generated method stub if((rear+1)%maxSize==front){ System.out.println("队列已满..."); return; } rear=(rear+1)%maxSize; objects[rear]=object; size++; } @Override public Object remove() { // TODO Auto-generated method stub if(front==rear){ System.out.println("队列已经空了..."); return null; } front=(front+1)%maxSize; Object object = objects[front]; size--; return object; } @Override public int getSize() { // TODO Auto-generated method stub return size; } @Override public Object peek() { // TODO Auto-generated method stub return objects[front+1]; } @Override public boolean isEmpty() { // TODO Auto-generated method stub return front==rear; } public static void main(String[] args) { MyQueue queue = new MyArrayCircularQueue(); for(int i=0;i<50;i++){ queue.add("str"+i); } while(!queue.isEmpty()){ Object object=queue.remove(); System.out.println((String)object); } } }
循环队列的示意图