基于链表、数组实现队列、循环队列

来源:互联网 发布:redis面试题 php 编辑:程序博客网 时间:2024/05/18 00:38

队列是一种先进先出的数据结构,它和栈的性质正好相反,但是两者却经常结合在一起实现一些特殊的操作。

1.队列的接口

public interface QueueADT {//入队public void enqueue(Object element);//出队public Object dequeue();//返回队首元素public Object first();//是否为空public boolean isEmpty();//返回队列大小public int size();public String toString();}

2.链表实现队列

public class LinkedQueue implements QueueADT {// 链表节点类,内部类实现,包含数据域和指针域class Node {int data; // 数据域Node next;// 指针域public Node(int data) {this.data = data;}} //指向队首、队尾节点private Node front,rear;//维护队列的大小private int count;public LinkedQueue() {front=null;rear=null;count=0;}//保证出栈或者出队列的是头结点,这样才能完成更新,所以对于栈的入栈操作,是从尾节点开始构造的//队列的入队操作,是从头结点开始构造的@Overridepublic void enqueue(Object element) {Node node=new Node((Integer)element);if(isEmpty()){front=rear=node;}else{rear.next=node;rear=node;}count++;}@Overridepublic Object dequeue() {if(isEmpty()){            System.out.println("队列中没有元素");            System.exit(1);        }Object result=front.data;front=front.next;count--;return result;}@Overridepublic Object first() {return front.data;}@Overridepublic boolean isEmpty() {return (size()==0);}@Overridepublic int size() {return count;}public static void main(String[] args) {                LinkedQueue queue = new LinkedQueue();                System.out.println("依次将0到9入队,然后连续出队5次");        for(int i = 0;i < 10;i++)            queue.enqueue(i);        for(int i = 0;i < 5;i++)            queue.dequeue();        System.out.println("队列的大小为: " + queue.size());        System.out.println("队列为空吗?: " + queue.isEmpty());        System.out.println("队列的头为: " + queue.first());    }}


3.数组实现队列

//用数组实现队列,如果队首不固定,随着出队操作,数组前面的空间就被浪费,但是如果队首固定,每次出队都要移动所有元素public class ArrayQueue implements QueueADT {private Object[] contents;//由于数组实现,rear是一个整数指针,指向数组的索引即可private int rear;private static int SIZE = 10;public ArrayQueue(){        contents = new Object[SIZE];        rear = 0;    }public void expand(){        Object[] larger = new Object[size()*2];        for(int index = 0;index < rear;index++)            larger[index] = contents[index];                contents = larger;    }@Overridepublic void enqueue(Object element) {if(rear == contents.length)            expand();        contents[rear] = element;        rear++;}@Overridepublic Object dequeue() {if(isEmpty()){            System.out.println("队列为空");            System.exit(1);        }        Object result = contents[0];        //为了保证队首固定,每次出队之后都要移动元素        for(int index = 0;index < rear;index++)                contents[index] = contents[index+1];        rear--;        return result;        }@Overridepublic Object first() {return contents[0];}@Overridepublic boolean isEmpty() {return (size()==0);}@Overridepublic int size() {return rear;}}

4.数组实现循环队列 

//使用循环队列可以消除元素频繁移动带来的效率问题,用两个指针分别指向队首和队尾,走到数组末尾时,在数组头部继续入队public class CircularArrayQueue implements QueueADT{private Object[] contents;    private int front,rear;//front为队头下标,rear为队尾的下一个元素的下标    private int count;//标记队列元素个数    private static int SIZE = 10;            public CircularArrayQueue(){        contents = new Object[SIZE];        front = -1;        rear = 0;        count = 0;    }//对栈还有队列进行操作,或者其他类,一般都要特殊考虑一下状态为空或者初始化时的特殊值    @Overridepublic void enqueue(Object element) {if(isEmpty()){contents[0]=element;front=0;rear=1;count++;}else{contents[rear]=element;rear=(rear+1)%contents.length;count++;}}@Overridepublic Object dequeue() {if(isEmpty()){            System.out.println("队列为空!!!");            System.exit(1);        }Object result = contents[front];        front = (front + 1) % contents.length;        count--;        return result;    }@Overridepublic Object first() {return contents[front];}@Overridepublic boolean isEmpty() {return (size()==0);}@Overridepublic int size() {return count;}}



0 0
原创粉丝点击