java 队列存储结构_Java队列存储结构及实现

一、队列(Queue)

队列是一种特殊的线性表,它只允许在表的前段(front)进行删除操作,只允许在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。

对于一个队列来说,每个元素总是从队列的rear端进入队列,然后等待该元素之前的所有元素出队之后,当前元素才能出对,遵循先进先出(FIFO)原则。

如果队列中不包含任何元素,该队列就被称为空队列。

Java提供了一个Queue接口,并为该接口提供了众多的实现类:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、PriorityQueue、ConcurrentLinkedQueue和SynchronousQueue。

其中常用的是:ArrayBlockingQueue、LinkedBlockingQueue和CurrentLinkedQueue,它们都是线程安全的队列。LinkedBlockingQueue队列的吞吐量通常比ArrayBlockingQueue队列高,但在大多数并发应用程序中,LinkedBlockingQueue的性能要低。

除了LinkedBlockingQueue队列之外,JDK还提供了另外一种链队列ConcurrentLinkedQueue,它基于一种先进的、无等待(wait-free)队列算法实现。

二、顺序队列存储结构的实现

1 packagecom.ietree.basic.datastructure.queue;2

3 importjava.util.Arrays;4

5 /**

6 * Created by ietree7 * 2017/4/298 */

9 public class SequenceQueue{10

11 private int DEFAULT_SIZE = 10;12 //保存数组的长度

13 private intcapacity;14 //定义一个数组用于保存顺序队列的元素

15 privateObject[] elementData;16 //保存顺序队列中元素的当前个数

17 private int front = 0;18 private int rear = 0;19

20 //以默认数组长度创建空顺序队列

21 publicSequenceQueue() {22

23 capacity =DEFAULT_SIZE;24 elementData = newObject[capacity];25

26 }27

28 //以一个初始化元素来创建顺序队列

29 publicSequenceQueue(T element) {30

31 this();32 elementData[0] =element;33 rear++;34

35 }36

37 /**

38 * 以指定长度的数组来创建顺序线性表39 *40 *@paramelement 指定顺序队列中第一个元素41 *@paraminitSize 指定顺序队列底层数组的长度42 */

43 public SequenceQueue(T element, intinitSize) {44

45 this.capacity =initSize;46 elementData = newObject[capacity];47 elementData[0] =element;48 rear++;49 }50

51 /**

52 * 获取顺序队列的大小53 *54 *@return顺序队列的大小值55 */

56 public intlength() {57

58 return rear -front;59

60 }61

62 /**

63 * 插入队列64 *65 *@paramelement 入队列的元素66 */

67 public voidadd(T element) {68

69 if (rear > capacity - 1) {70 throw new IndexOutOfBoundsException("队列已满异常");71 }72 elementData[rear++] =element;73

74 }75

76 /**

77 * 移除队列78 *79 *@return出队列的元素80 */

81 publicT remove() {82

83 if(empty()) {84 throw new IndexOutOfBoundsException("空队列异常");85 }86

87 //保留队列的rear端的元素的值

88 T oldValue =(T) elementData[front];89 //释放队列顶元素

90 elementData[front++] = null;91 returnoldValue;92

93 }94

95 //返回队列顶元素,但不删除队列顶元素

96 publicT element() {97

98 if(empty()) {99 throw new IndexOutOfBoundsException("空队列异常");100 }101 return(T) elementData[front];102

103 }104

105 //判断顺序队列是否为空

106 public booleanempty() {107

108 return rear ==front;109

110 }111

112 //清空顺序队列

113 public voidclear() {114

115 //将底层数组所有元素赋值为null

116 Arrays.fill(elementData, null);117 front = 0;118 rear = 0;119

120 }121

122 publicString toString() {123

124 if(empty()) {125

126 return "[]";127

128 } else{129

130 StringBuilder sb = new StringBuilder("[");131 for (int i = front; i < rear; i++) {132 sb.append(elementData[i].toString() + ", ");133 }134 int len =sb.length();135 return sb.delete(len - 2, len).append("]").toString();136 }137

138 }139

140 }

测试类:

1 packagecom.ietree.basic.datastructure.queue;2

3 /**

4 * Created by ietree5 * 2017/4/306 */

7 public classSequenceQueueTest {8

9 public static voidmain(String[] args) {10

11 SequenceQueue queue = new SequenceQueue();12 //依次将4个元素加入到队列中

13 queue.add("aaaa");14 queue.add("bbbb");15 queue.add("cccc");16 queue.add("dddd");17 System.out.println(queue);18

19 System.out.println("访问队列的front端元素:" +queue.element());20

21 System.out.println("第一次弹出队列的front端元素:" +queue.remove());22

23 System.out.println("第二次弹出队列的front端元素:" +queue.remove());24

25 System.out.println("两次remove之后的队列:" +queue);26 }27

28 }

程序输出:

[dddd, cccc, bbbb, aaaa]

访问栈顶元素:dddd

第一次弹出栈顶元素:dddd

第二次弹出栈顶元素:cccc

两次pop之后的栈:[bbbb, aaaa]

三、队列的链式存储结构实现

1 packagecom.ietree.basic.datastructure.queue;2

3 /**

4 * Created by ietree5 * 2017/4/306 */

7 public class LinkQueue{8

9 //定义一个内部类Node,Node实例代表链队列的节点

10 private classNode {11

12 //保存节点的数据

13 privateT data;14 //指向下个节点的引用

15 privateNode next;16

17 //无参构造器

18 publicNode() {19 }20

21 //初始化全部属性的构造器

22 publicNode(T data, Node next) {23

24 this.data =data;25 this.next =next;26

27 }28

29 }30

31 //保存该链队列的头节点

32 privateNode front;33 //保存该链队列的尾节点

34 privateNode rear;35 //保存该链队列中已包含的节点数

36 private intsize;37

38 //创建空链队列

39 publicLinkQueue() {40 //空链队列,front和rear的值都为null

41 front = null;42 rear = null;43 }44

45 //以指定数据元素来创建链队列,该链队列只有一个元素

46 publicLinkQueue(T element) {47

48 front = new Node(element, null);49 //只有一个节点,front、rear都是指向该节点

50 rear =front;51 size++;52

53 }54

55 //返回链队列的长度

56 public intlength() {57

58 returnsize;59

60 }61

62 //将新元素加入队列

63 public voidadd(T element) {64 //如果该链队列还是空链队列

65 if (front == null) {66 front = new Node(element, null);67 //只有一个节点,front、rear都是指向该节点

68 rear =front;69 } else{70 //创建新节点

71 Node newNode = new Node(element, null);72 //让尾节点的next指向新增的节点

73 rear.next =newNode;74 rear =newNode;75 }76 size++;77 }78

79 //删除队列front端的元素

80 publicT remove() {81

82 Node oldfront =front;83 //让front引用指向原队列顶元素的下一个元素

84 front =front.next;85 //释放原队列顶元素的next引用

86 oldfront.next = null;87 size--;88 returnoldfront.data;89

90 }91

92 //访问队列顶元素,但不删除队列顶元素

93 publicT element() {94

95 returnrear.data;96

97 }98

99 //判断链队列是否为空队列

100 public booleanempty() {101

102 return size == 0;103

104 }105

106 //请空链队列

107 public voidclear() {108 //将front、rear两个节点赋为null

109 front = null;110 rear = null;111 size = 0;112 }113

114 publicString toString() {115

116 //链队列为空队列时

117 if(empty()) {118 return "[]";119 } else{120 StringBuilder sb = new StringBuilder("[");121 for (Node current = front; current != null; current =current.next) {122 sb.append(current.data.toString() + ", ");123 }124 int len =sb.length();125 return sb.delete(len - 2, len).append("]").toString();126 }127

128 }129

130 }

测试类:

1 packagecom.ietree.basic.datastructure.queue;2

3 /**

4 * Created by ietree5 * 2017/4/306 */

7 public classLinkQueueTest {8

9 public static voidmain(String[] args) {10

11 LinkQueue queue = new LinkQueue("aaaa");12 //依次将4个元素加入到队列中

13 queue.add("bbbb");14 queue.add("cccc");15 queue.add("dddd");16 System.out.println(queue);17

18 //删除一个元素后

19 queue.remove();20 System.out.println("删除一个元素后的队列:" +queue);21

22 //再添加一个元素

23 queue.add("eeee");24 System.out.println("再次添加元素后的队列:" +queue);25

26 }27

28 }

程序输出:

[aaaa, bbbb, cccc, dddd]

删除一个元素后的队列:[bbbb, cccc, dddd]

再次添加元素后的队列:[bbbb, cccc, dddd, eeee]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值