队列的定义:

队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。

java队列和链表区别 队列和链表的区别_出队

(1)允许删除的一端称为队头(Front)。

(2)允许插入的一端称为队尾(Rear)。
(3)当队列中没有元素时称为空队列。
(4)队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表。
   队列的修改是依先进先出的原则进行的。新来的成员总是加入队尾,每次离开的成员总是队列头上的(不允许中途离队)。

队列的存储结构及实现

队列的顺序存储结构

(1) 顺序队列的定义:

 队列的顺序存储结构称为顺序队列,顺序队列实际上是运算受限的顺序表。

(2)顺序队列的表示:

和顺序表一样,顺序队列利用内存中一段连续的存储空间来存放当前队列中的元素。
由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素,它们的初值在队列初始化时均应置为0。

 

java队列和链表区别 队列和链表的区别_链队列_02

(3)顺序队列的基本操作




入队时:将新元素插入rear所指的位置的后一位。
出队时:删去front所指的元素,然后将front加1并返回被删元素。

(4)顺序表的溢出现象

 ①“下溢”现象
 当队列为空时,做出队运算产生的溢出现象。“下溢”是正常现象,常用作程序控制转移的条件。

② "真上溢"现象
当队列满时,做进栈运算产生空间溢出的现象。“真上溢”是一种出错状态,应设法避免。

③ "假上溢"现象
由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。当队列中实际的元素个数远远小于内存中本分配的空间时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。该现象称为"假上溢"现象。如下图

java队列和链表区别 队列和链表的区别_System_03

 如上图所示,这种头尾相接的顺序存储结构称为循环队列(circular queue)。

循环队列中需要注意的几个重要问题:

①队空的判定条件,队空的条件是front=rear;

②队满的判定条件,(rear+1)%QueueSize=front。QueueSize为队列初始空间大小。

循环队列的java实现代码

[java]  view plain copy


二 :链表实现

1. package study_02.datastructure.queue;  
2.   
3. /**
4.  * 循环队列
5.  * @author WWX
6.  */  
7. public class CirQueue<E> {  
8. //对象数组,队列最多存储a.length-1个对象  
9.     E[] a;  
10. //默认初始化大小  
11. private static final int DEFAULT_SIZE=10;  
12. //对首下标  
13. int front;  
14. //队尾下标  
15. int rear;  
16.       
17. public CirQueue(){  
18. this(DEFAULT_SIZE);  
19.     }  
20. /**
21.      * 初始化指定长度的队列
22.      * @param size
23.      */  
24. @SuppressWarnings("unchecked")  
25. public CirQueue(int size){  
26. new Object[size]);  
27. 0;  
28. 0;  
29.     }  
30.       
31. /**
32.      * 将一个对象追加到队列尾部
33.      * @param obj
34.      * @return 队列满时返回false,否则返回true
35.      * @author WWX
36.      */  
37. public boolean enqueue(E obj){  
38. if((rear+1)%a.length==front){  
39. return false;  
40. else{  
41.             a[rear]=obj;  
42. 1)%a.length;  
43. return true;  
44.         }  
45.     }  
46.       
47. /**
48.      * 队列头部出队
49.      * @return
50.      * @author WWX
51.      */  
52. public E dequeue(){  
53. if(rear==front)  
54. return null;  
55. else{  
56.             E obj =a[front];  
57. 1)%a.length;  
58. return obj;  
59.         }  
60.     }  
61.       
62. /**
63.      * 队列长度
64.      * @return
65.      * @author WWX
66.      */  
67. public  int size(){  
68. return (rear-front)&(a.length-1);  
69.     }  
70. //队列长度(另一种方法)  
71. public int length(){  
72. if(rear>front){  
73. return rear-front;  
74. else  
75. return a.length-1;  
76.     }  
77.       
78. /**
79.      * 判断是否为空 
80.      * @return
81.      * @author WWX
82.      */  
83. public boolean isEmpty(){  
84. return rear==front;  
85.     }  
86.       
87.   
88.   
89. public static void main(String[] args) {  
90. new CirQueue<String>(4);  
91. "1");  
92. "2");  
93. "3");  
94. "size="+queue.size());  
95. int size=queue.size();  
96. "*******出栈操作*******");  
97. for(int i=0; i<size;i++){  
98. " ");  
99.         }  
100.           
101.     }  
102.       
103. }

在上一篇博文中通过java实现了队列的连续存储,下面来讨论队列的链式存储,即链队列。

链队列的定义:

队列的链式存储结构简称为链队列。它是限制仅在表头删除和表尾插入的单链表。

链队列的数据存储形式:

java队列和链表区别 队列和链表的区别_链队列_04


[java]  view plain copy



    1. package study_02.datastructure.queue;  
    2.   
    3.   
    4. /**
    5.  * 链队列
    6.  * @author WWX
    7.  */  
    8. public class LinkQueue<T> {  
    9.       
    10. //链的数据结构  
    11. private class Node{  
    12. public  T data;  
    13. public  Node next;  
    14. //无参构造函数  
    15. public Node(){}  
    16.           
    17. public Node(T data,Node next){  
    18. this.data=data;  
    19. this.next=next;  
    20.         }  
    21.     }  
    22. //队列头指针  
    23. private Node front;  
    24. //队列尾指针  
    25. private Node rear;  
    26. //队列长度  
    27. private int size=0;  
    28.       
    29. public LinkQueue(){  
    30. new Node(null,null);  
    31. null;  
    32.         front=rear=n;  
    33.     }  
    34.       
    35. /**
    36.      * 队列入队算法
    37.      * @param data
    38.      * @author WWX
    39.      */  
    40. public void enqueue(T data){  
    41. //创建一个节点  
    42. new Node(data,null);  
    43. //将队尾指针指向新加入的节点,将s节点插入队尾  
    44.         rear.next=s;  
    45.         rear=s;  
    46.         size++;  
    47.     }  
    48.       
    49. /**
    50.      * 队列出队算法
    51.      * @return
    52.      * @author WWX
    53.      */  
    54. public  T dequeue(){  
    55. if(rear==front){  
    56. try {  
    57. throw new Exception("堆栈为空");  
    58. catch (Exception e) {  
    59.                 e.printStackTrace();  
    60.             }  
    61. return null;  
    62. else{  
    63. //暂存队头元素  
    64.             Node p=front.next;  
    65.             T x=p.data;  
    66. //将队头元素所在节点摘链  
    67.             front.next=p.next;  
    68. //判断出队列长度是否为1  
    69. if(p.next==null)  
    70.                 rear=front;  
    71. //删除节点  
    72. null;  
    73.             size--;  
    74. return  x;  
    75.         }  
    76.     }  
    77.       
    78. /**
    79.      * 队列长队
    80.      * @return
    81.      * @author WWX
    82.      */  
    83. public int size(){  
    84. return size;  
    85.     }  
    86.       
    87. /**
    88.      * 判断队列是否为空
    89.      * @return
    90.      * @author WWX
    91.      */  
    92. public  boolean isEmpty(){  
    93. return  size==0;  
    94.           
    95.     }  
    96.       
    97.       
    98. public String toString() {  
    99. if(isEmpty()){  
    100. return "[]";  
    101. else{  
    102. new StringBuilder("[");  
    103. for(Node current=front.next;current!=null;current=current.next){  
    104. ", ");  
    105.             }  
    106. int len = sb.length();  
    107. return sb.delete(len - 2, len).append("]").toString();  
    108.         }  
    109.     }  
    110.       
    111. //测试  
    112. public static void main(String[] args) {  
    113. new LinkQueue<Integer>();  
    114. 1);  
    115. 2);  
    116. 3);  
    117. 4);  
    118. 5);  
    119. 6);  
    120.         System.out.println(queue);  
    121. "出队:"+queue.dequeue());  
    122. "队列长度="+queue.size());  
    123.         System.out.println(queue);  
    124. "出队:"+queue.dequeue());  
    125. "队列长度="+queue.size());  
    126.         System.out.println(queue);  
    127. "出队:"+queue.dequeue());  
    128. "队列长度="+queue.size());  
    129.         System.out.println(queue);  
    130.     }  
    131. }


     

    输出结果:

    [1, 2, 3, 4, 5, 6]
    出队:1
    队列长度=5
    [2, 3, 4, 5, 6]
    出队:2
    队列长度=4
    [3, 4, 5, 6]
    出队:3
    队列长度=3
    [4, 5, 6]