Java队列存储结构及实现

一、队列(Queue)

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

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

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

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

  1 package com.ietree.basic.datastructure.queue;
  2
  3 import java.util.Arrays;
  4
  5 /**
  6  * Created by ietree
  7  * 2017/4/29
  8  */
  9 public class SequenceQueue<T> {
 10
 11     private int DEFAULT_SIZE = 10;
 12     // 保存数组的长度
 13     private int capacity;
 14     // 定义一个数组用于保存顺序队列的元素
 15     private Object[] elementData;
 16     // 保存顺序队列中元素的当前个数
 17     private int front = 0;
 18     private int rear = 0;
 19
 20     // 以默认数组长度创建空顺序队列
 21     public SequenceQueue() {
 22
 23         capacity = DEFAULT_SIZE;
 24         elementData = new Object[capacity];
 25
 26     }
 27
 28     // 以一个初始化元素来创建顺序队列
 29     public SequenceQueue(T element) {
 30
 31         this();
 32         elementData[0] = element;
 33         rear++;
 34
 35     }
 36
 37     /**
 38      * 以指定长度的数组来创建顺序线性表
 39      *
 40      * @param element  指定顺序队列中第一个元素
 41      * @param initSize 指定顺序队列底层数组的长度
 42      */
 43     public SequenceQueue(T element, int initSize) {
 44
 45         this.capacity = initSize;
 46         elementData = new Object[capacity];
 47         elementData[0] = element;
 48         rear++;
 49     }
 50
 51     /**
 52      * 获取顺序队列的大小
 53      *
 54      * @return 顺序队列的大小值
 55      */
 56     public int length() {
 57
 58         return rear - front;
 59
 60     }
 61
 62     /**
 63      * 插入队列
 64      *
 65      * @param element 入队列的元素
 66      */
 67     public void add(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     public T 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         return oldValue;
 92
 93     }
 94
 95     // 返回队列顶元素,但不删除队列顶元素
 96     public T element() {
 97
 98         if (empty()) {
 99             throw new IndexOutOfBoundsException("空队列异常");
100         }
101         return (T) elementData[front];
102
103     }
104
105     // 判断顺序队列是否为空
106     public boolean empty() {
107
108         return rear == front;
109
110     }
111
112     // 清空顺序队列
113     public void clear() {
114
115         // 将底层数组所有元素赋值为null
116         Arrays.fill(elementData, null);
117         front = 0;
118         rear = 0;
119
120     }
121
122     public String 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 package com.ietree.basic.datastructure.queue;
 2
 3 /**
 4  * Created by ietree
 5  * 2017/4/30
 6  */
 7 public class SequenceQueueTest {
 8
 9     public static void main(String[] args) {
10
11         SequenceQueue<String> queue = new SequenceQueue<String>();
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 package com.ietree.basic.datastructure.queue;
  2
  3 /**
  4  * Created by ietree
  5  * 2017/4/30
  6  */
  7 public class LinkQueue<T> {
  8
  9     // 定义一个内部类Node,Node实例代表链队列的节点
 10     private class Node {
 11
 12         // 保存节点的数据
 13         private T data;
 14         // 指向下个节点的引用
 15         private Node next;
 16
 17         // 无参构造器
 18         public Node() {
 19         }
 20
 21         // 初始化全部属性的构造器
 22         public Node(T data, Node next) {
 23
 24             this.data = data;
 25             this.next = next;
 26
 27         }
 28
 29     }
 30
 31     // 保存该链队列的头节点
 32     private Node front;
 33     // 保存该链队列的尾节点
 34     private Node rear;
 35     // 保存该链队列中已包含的节点数
 36     private int size;
 37
 38     // 创建空链队列
 39     public LinkQueue() {
 40         // 空链队列,front和rear的值都为null
 41         front = null;
 42         rear = null;
 43     }
 44
 45     // 以指定数据元素来创建链队列,该链队列只有一个元素
 46     public LinkQueue(T element) {
 47
 48         front = new Node(element, null);
 49         // 只有一个节点,front、rear都是指向该节点
 50         rear = front;
 51         size++;
 52
 53     }
 54
 55     // 返回链队列的长度
 56     public int length() {
 57
 58         return size;
 59
 60     }
 61
 62     // 将新元素加入队列
 63     public void add(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     public T remove() {
 81
 82         Node oldfront = front;
 83         // 让front引用指向原队列顶元素的下一个元素
 84         front = front.next;
 85         // 释放原队列顶元素的next引用
 86         oldfront.next = null;
 87         size--;
 88         return oldfront.data;
 89
 90     }
 91
 92     // 访问队列顶元素,但不删除队列顶元素
 93     public T element() {
 94
 95         return rear.data;
 96
 97     }
 98
 99     // 判断链队列是否为空队列
100     public boolean empty() {
101
102         return size == 0;
103
104     }
105
106     // 请空链队列
107     public void clear() {
108         // 将front、rear两个节点赋为null
109         front = null;
110         rear = null;
111         size = 0;
112     }
113
114     public String 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 package com.ietree.basic.datastructure.queue;
 2
 3 /**
 4  * Created by ietree
 5  * 2017/4/30
 6  */
 7 public class LinkQueueTest {
 8
 9     public static void main(String[] args) {
10
11         LinkQueue<String> queue = new LinkQueue<String>("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]
时间: 2024-10-14 10:31:58

Java队列存储结构及实现的相关文章

二叉树的链式存储结构----二叉链表

头文件:head.h #include<string.h> #include<ctype.h> #include<malloc.h> /* malloc()等 */ #include<limits.h> /* INT_MAX等 */ #include<stdio.h> /* EOF(=^Z或F6),NULL */ #include<stdlib.h> /* atoi() */ #include<io.h> /* eof()

存储结构与邻接矩阵,深度优先和广度优先遍历及Java实现

如果看完本篇博客任有不明白的地方,可以去看一下<大话数据结构>的7.4以及7.5,讲得比较易懂,不过是用C实现 下面内容来自segmentfault 存储结构 要存储一个图,我们知道图既有结点,又有边,对于有权图来说,每条边上还带有权值.常用的图的存储结构主要有以下二种: 邻接矩阵 邻接表 邻接矩阵 我们知道,要表示结点,我们可以用一个一维数组来表示,然而对于结点和结点之间的关系,则无法简单地用一维数组来表示了,我们可以用二维数组来表示,也就是一个矩阵形式的表示方法. 我们假设A是这个二维数组

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

队列的存储结构和常见操作(c 语言实现)

一.队列(queue) 队列和栈一样,在实际程序的算法设计和计算机一些其他分支里,都有很多重要的应用,比如计算机操作系统对进程 or 作业的优先级调度算法,对离散事件的模拟算法,还有计算机主机和外部设备运行速度不匹配的问题解决等,很多很多.其实队列的本质还是线性表!只不过是一种特殊的或者说是受限的线性表,是这样的: 1).限定在表的一端插入.另一端删除. 插入的那头就是队尾,删除的那头就是队头.也就是说只能在线性表的表头删除元素,在表尾插入元素.形象的说就是水龙头和水管,流水的水嘴是队头,进水的

队列的链式存储结构

1 链队列的存储结构 将对头指针front指向链队列的头结点,队尾指针rear指向终端结点. 空队列时,头指针front和尾指针rear都指向头结点. 链队列的存储结构为: typedef int QElemType; typedef struct QNode { //结点结构 QElemType data; struct QNode *next; }QNode; typedef struct QNode * QueuePtr; typedef struct { //队列的链表结构 QueueP

队列的顺序存储结构和链式存储结构

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表(在队尾进行插入操作,在对头进行删除操作). 与栈相反,队列是一种先进先出(First In First Out, FIFO)的线性表. 与栈相同的是,队列也是一种重要的线性结构,实现一个队列同样需要顺序表或链表作为基础. 队列的链式存储结构 队列既可以用链表实现,也可以用顺序表实现.跟栈相反的是,栈一般我们用顺序表来实现,而队列我们常用链表来实现,简称为链队列. typedef struct QNode { ElemT

数据结构:队列的链式存储结构

链队列的实现方法: 队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,简称为链队列.为了操作上的方便,我们将队头指针指向链队列的头节点,而队尾指针指向终端节点.空队列时,front和rear都指向头节点. 注意:这里的实现是有头结点的,在队列的初始化函数中要为头结点开辟空间. 链队列的实现代码: #include <iostream> #include <stdlib.h> using namespace std; /**********************

【Java数据结构学习笔记之一】线性表的存储结构及其代码实现

应用程序后在那个的数据大致有四种基本的逻辑结构: 集合:数据元素之间只有"同属于一个集合"的关系 线性结构:数据元素之间存在一个对一个的关系 树形结构:数据元素之间存在一个对多个关系 图形结构或网状结构:数据元素之间存在多个对多个的关系 对于数据不同的逻辑结构,计算机在物理磁盘上通常有两种屋里存储结构 顺序存储结构 链式存储结构 本篇博文主要讲的是线性结构,而线性结构主要是线性表,非线性结构主要是树和图. 线性表的基本特征: 总存在唯一的第一个数据元素 总存在唯一的最后一个数据元素 除

栈的链式存储结构及应用(C、Java代码)

链式存储结构最大的好处就是没有空间的限制,可以通过指针指向将结点像以链的形式把结点链接,我们熟悉的线性表就有链式存储结构. 当然,栈同样有链式存储结构,栈的链式存储结构,简称链栈. 从图片可以看到,和单链表很像,拥有一个头指针top,又称作栈顶指针,所以此时就不再需要单链表里面的头结点了. 对于链栈来说,基本不存在栈满的情况,除非计算机内存已经没有了可使用的空间,如果真的存在,那么计算机系统已经面临着即将死机崩溃的情况,而不是这个链栈是否溢出的问题了. 对于空栈来说,链表的定义是头指针指向NUL