关于JAVA数据结构_队列(通过顺序和链式实现)

2-2 队列

2-2-1 队列的特点及抽象数据类型
队列(Queue)简称为队,也是一种受限的线性表,值允许在线性表的一端进行插入,而在表的另一端进行删除
称插入数据的一端为队尾(rear),称删除数据的一端为队首 (front).
向队列添加数据称为入队或进队,新入队的元素称为队尾元素,在队列中删除元素称为出队或离队,元素出队之后,它的后续元素称为新的队首元素.
队列是一种先进先出(First in First Out 简称 FIFO)
 队列抽象数据类型的定义:
       ADT Queue{
            数据对象:D={a0,a1,a2...an,ai 都是同一数据类型的 元素}
            数据关系:R={ai,ai+1}
            数据操作:
                getSize():返回元素个数
                isEmpty():判断队列是否为空
                enQueue(e):入队
                deQueue():出队
                peek():返回队首的元素

            }ADT Queue

2-2-2 队列的顺序存储实现
在队列的实现中,可以把数组设想成一个圆环,这种数组称为循环数组,用循环数组晒西安的队列称为循环队列
用front指针指向 队首元素所在的单位,使用rear指针指向队尾元素所在的后一个单元
在元素入队时,将新入队的元素保存到rear指向的单元,然后rear指向后移;在出队时,将队首指针指向front指向的元素返回,然后front后移
一般情况下,我们用以下两种方式表示队列已满:
1.少用一个存储单元,当队尾指针rear指向下一个单元是队首指针front时,停止入队,(rear+1)%capacity==front时表示队列已满,当front==rear时表示队列为空
2.增设一个标志表示队列为空还是满,通常用size变量表示元素的个数,当size==0时队列为空,当size==capacity时表示队列已满.

 1 package demo4.queue;
 2 /**
 3  * 队列的顺序存储实现 通过数组
 4  * @author ASUS
 5  *
 6  */
 7 public class MyArrayQueue {
 8     private Object[] elements;
 9     private static final int DEFAULT_CAPACITY=8;
10     private int front;
11     private int rear;
12     private int size;
13     
14     
15     public MyArrayQueue(){
16         elements =new Object[DEFAULT_CAPACITY];
17         
18     }
19     public MyArrayQueue(int initialCapacity){
20         elements=new Object[initialCapacity];
21                 
22     }
23     //返回元素的个数
24     public int getSize(){
25         return size;
26     }
27     //判断队列是否为空
28     public boolean isEmpty(){
29         return size==0;
30     }
31     //入队
32     public void enQueue(Object e){
33         //如果队列已满,数组扩容
34         if(size>=elements.length){
35             expandQueue();
36         }
37         elements[rear]=e;           //把元素存储到rear指向的单元
38         rear=(rear+1)%elements.length;   //rear指针后移1
39         size++;
40     }
41     //对数组进行扩容
42     private void expandQueue() {
43         //定义更大的数组
44         Object[] newElements=new Object[elements.length*2];
45         
46         //把原来的内容复制到新数组,从队首开始依次复制到新数组索引0开始的位置
47         for(int i=0;i<elements.length;i++){
48             newElements[i]=elements[front];
49             front=(front+1%elements.length);
50                     }
51         //把原来的数组名指向新的数组
52         elements=newElements;
53         //调整新的队首位置
54         front=0;
55         rear=size;
56             }
57     //出队
58     public Object deQueue(){
59         //如果队列为空
60         if(size<=0){
61             //抛异常
62             throw new QueueEmptyException("队列为空");
63         }
64         //如果队列不为空,把front指向元素返回
65         Object old =elements[front];
66         front=(front+1)%elements.length;
67         size--;
68         return old;
69     }
70     public Object peek(){
71         //队列为空,跑异常
72         if(size<=0){
73             throw new QueueEmptyException("队列为空");
74             
75         }
76         return elements[front];
77     }
78     
79 }
 1 package demo4.queue;
 2 /**
 3  * 测试顺序存储的队列
 4  * @author ASUS
 5  *
 6  */
 7 public class TestQueue {
 8 
 9     public static void main(String[] args) {
10         System.out.println("测试顺序存储");
11         MyArrayQueue queue=new MyArrayQueue();
12         queue.enQueue("a");
13         queue.enQueue("b");
14         queue.enQueue("c");
15         queue.enQueue("d");
16         System.out.println(queue.getSize());
17         System.out.println(queue.peek());
18         System.out.println(queue.deQueue());
19         
20     }
21 
22 }

运行截图:

 1 package demo4.queue;
 2 /**
 3  * 自定义队列为空的异常
 4  * 该异常为一个运行异常
 5  * RuntimeException的子类就是运行异常
 6  * @author ASUS
 7  *
 8  */
 9 public class QueueEmptyException extends RuntimeException{
10 
11     public QueueEmptyException() {
12         super();
13         
14     }
15 
16     
17     //String 参数,传递异常的信息
18     public QueueEmptyException(String message) {
19         super(message);
20         
21     }
22 
23     
24 
25     
26 }

2-2-3 队列的链式存储

 1 package demo4.queue;
 2 
 3 /**
 4  * 队列的链式存储
 5  * @author ASUS
 6  *
 7  */
 8 public class MyLinkQueue {
 9     private Node front;
10     private Node rear;
11     private int size;
12     
13     //返回元素个数
14     public int getSize(){
15         return size;
16     }
17     //判断队列是否为空
18     public boolean isEmpty(){
19         return size==0;
20     }
21     //入队
22     public void enQueue(Object e){
23         //根据添加的元素生成一个结点
24         Node newNode=new Node(e,null);
25         //把结点连接到队列中
26         if(rear==null){
27             //这是添加的第一个元素,即是头结点也是尾结点
28             rear = newNode;
29             front=newNode;
30         }else{
31             //把结点链拉到尾部
32             rear.next=newNode;
33             rear=newNode;    //rear指针指向新添加的元素
34         }
35         size++;  //元素个数加1
36     }
37     
38     //出队
39     public Object deQueue(){
40         //判断队列是否为空
41         if(size<=0){
42             throw new QueueEmptyException("队列为空");
43         }
44         Object old=front.elements;
45         front =front.next;
46         //如果出队后,队列为空,调整尾指针
47         if(front==null){
48             rear=null;
49         }
50         size --;
51         return old;        
52     }
53     //返回队首元素
54     public Object peek(){
55         if(size<=0){
56             throw new QueueEmptyException("队列为空");
57             
58         }
59         return front.elements;
60     }
61     //通过内部类表示单向链表的结点
62     private class Node{
63         Object elements;
64         Node next;
65         public Node(Object elements, Node next) {
66             super();
67             this.elements = elements;
68             this.next = next;
69         }
70         
71     }
72     
73 }
 1 package demo4.queue;
 2 /**
 3  * 测试顺序存储的队列
 4  * @author ASUS
 5  *
 6  */
 7 public class TestQueue {
 8 
 9     public static void main(String[] args) {
10        
11         
12         System.out.println("测试链式存储");
13         MyLinkQueue lqueue=new MyLinkQueue();
14         lqueue.enQueue("aa");
15         lqueue.enQueue("bb");
16         lqueue.enQueue("cc");
17         lqueue.enQueue("dd");
18         lqueue.enQueue("ee");
19         System.out.println(lqueue.getSize());
20         //返回队首
21         System.out.println(lqueue.peek());
22         System.out.println(lqueue.deQueue());
23         System.out.println(lqueue.getSize());
24         
25         
26     }
27 
28 }

运行截图:

原文地址:https://www.cnblogs.com/yumu77/p/13771742.html