1、队列的定义

队列(queue):是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

队列是一种先进先出的线性表,简称FIFO(First out firts in)。允许插入的一头是队尾,允许删除的一头是队头。

注意:

队列是线性表,也同样有类似线性表的各种操作,不同的就是插入数据只能在队尾进行,删除数据只能在队头进行。

2、循环队列

2.1 循环队列的定义

队列中front指针指向队头元素,rear指针指向队尾元素的下一个元素,这样当front==rear 时,此队列是空队列。

循环队列的定义是:队列头尾相接的顺序存储结构称为循环队列。

队列满的条件是:(rear+1)%Queuesize = front;

通用的计算队列长度的公式为:(rear-front+Queuesize)%Queue

2.2 队列的顺序存储

队列插入元素主要步骤:rear = (rear+1)%Queuesize;

队列删除元素主要步骤:front = (front+1)%Queuesize;

队列的顺序存储代码实现:

public class SqeQueue<E> {
ArrayList<E> queue = new ArrayList<E>(); final int MAXSIZE = 20;//循环队列的长度
int font;//对头
int rear;//队尾
/*
* 队列构造函数
*/
public SqeQueue(){
initQueue();
}
/*
* 队列初始化
*/
public void initQueue(){
font=0;
rear=0;
}
/*
* 队列的当前长度
*/
public int getLength(){
return (rear-font+1)%MAXSIZE;
}
/*
* 入队,队是在队尾入队
*/
public boolean addQueue(E e){
//队列满的判断
if((rear+1)%MAXSIZE == font){
System.out.println("队满");
}
//将e赋给队尾
queue.add(rear, e);
//rear 后移一位
rear =( rear+1) %MAXSIZE;
return true;
}
public E deleteQueue(){
//队列满的判断
if(font == rear){
System.out.println("队为空");
}
//队头元素赋值给e
E e = queue.get(font);
//对头后移一位
font = (font+1)%MAXSIZE;
return e;
} public static void main(String args[]){
SqeQueue<Object> sqeQueue = new SqeQueue<Object>();
sqeQueue.addQueue("zzzzz");
sqeQueue.addQueue("bbbbbb");
sqeQueue.addQueue("333333");
for(int i=0;i<=sqeQueue.getLength();i++){
System.out.println(sqeQueue.deleteQueue());
}
}
}

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

队列的链式存储结构,其实就是线性表的单链表,只不过它是尾进头出,我们把它简称为链队列。

队头指针指向链队列的头结点,队尾指针指向终端结点。

空队列时,front和rear都指向头结点。

入队操作时,其实就是在链表尾部插入结点。

出队操作时,其实就是头结点的后继结点出队,将头结点的后继改为它后面的结点,若链表除头结点外只剩一个元素,则需要将rear指向头结点。

package com.aclie.dataStructe4.queue;

public class LinkQueue {
Node2 rear;//队尾
Node2 front;//队头
int count=0;
/*
* 无参构造函数,初始化链表
*/
public LinkQueue(){
rear = front = null;
}
/*
* 有参构造函数,初始化链表
*/
public LinkQueue(Object obj){
front = new Node2(obj);
rear = front;
count++;
}
/*
* 得到链表的当前长度
*/
public int getLinkLength(){
return count;
}
/*
* 入队,在队尾插入元素
*/
public void addLinkQueue(Object obj){ if(front == null){//空队列,插入元素
front = new Node2(obj);
rear = front;
}else{//非空队列
Node2 p = new Node2(obj);//要插入的结点
rear.next2 = p;//将插入结点赋值给rear后继
rear = p;//更改rear,rear指向插入的结点 }
count++;
}
public Object deleteLinkQueue(Object obj){
if(rear == front){
System.out.println("参数错误");
}
Node2 s =front;//将要删除的结点暂存为结点s
Object data2= s.data;//获取要删除的元素
front = s.next2;//将原队头结点后继s.next2 赋值给头结点后继
if(rear == s){//若队头是队尾,则将删除后将rear指向队头
rear = front;
}
s.next2 = null;//释放要删除结点
count--;
return data2;//返回删除
} public void printLinkQueue(){
if(front == null){
System.out.println("无打印的参数");
}else{
Node2 cur = front;
while(cur != null){
System.out.println(cur.data);
cur = cur.next2;
}
} }
public static void main(String args[]){
LinkQueue linkQueue = new LinkQueue();
linkQueue.addLinkQueue("222214"); linkQueue.addLinkQueue("ewqtee"); linkQueue.addLinkQueue("35432654"); linkQueue.printLinkQueue();
System.out.println("...........");
linkQueue.deleteLinkQueue(linkQueue.front);
linkQueue.deleteLinkQueue(linkQueue.front);
linkQueue.deleteLinkQueue(linkQueue.front);
linkQueue.printLinkQueue(); }
}
class Node2{
Object data;//数字域
Node2 next2;//指针域
public Node2(Object d2){
this.data = d2;
}
}

4、总结

对应循环队列与链队列的比较,可以从以下两方面:

时间上:其实他们都是基本的常数时间,即O(1),不过循环队列是事先申请好的空间,使用期间不释放,而对于链队列,每次申请和释放存在一些时间开销,

如果入队出队频繁,则两者还是有细微差异的。

空间上:循环队列必须有一个固定的长度,这就造成了存储元素个数和空间上的浪费。而链队列不存在这个问题。尽管它需要一个指针域,会产生一些空间上的开销,但也可以接              受。所以空间上,链队列更加灵活。

总得来说,在可以确定队列长度最大值情况下,建议用循环队列,如果无法预估队列长度,则用链队列。

大话数据结构(十)java程序——队列的更多相关文章

  1. Java程序员进击书籍推荐

    计算机基础 计算机科学导论 计算机操作系统 操作系统原理及应用(Linux) Java 基础和进阶 疯狂Java讲义 Java 核心基础卷1/2 Java编程思想 Java 8实战 jls11 Eff ...

  2. Java程序员从笨鸟到菜鸟全部博客目录

    本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 大学上了一年半,接触java也一年半了,虽然中间也有其他东西的学习,但是还是以java为主 ...

  3. 《Java程序员由笨鸟到菜鸟》

    <Java程序员由笨鸟到菜鸟> 在众多朋友的支持和鼓励下,<Java程序员由菜鸟到笨鸟>电子版终于和大家见面了.本电子书涵盖了从java基础到javaweb开放框架的大部分内容 ...

  4. 【Java】 大话数据结构(7) 循环队列和链队列

    本文根据<大话数据结构>一书,实现了Java版的循环队列.链队列. 队列:只允许在一端进行插入操作,而在另一端进行删除操作的线性表. 1.循环队列 队列的顺序储存结构:用数组存储队列,引入 ...

  5. 大话数据结构(八)Java程序——双向链表的实现

    线性链表--双向链表 双向链表定义: 双向链表(double linked list): 是在单表单的每个结点中,再设置一个指向前驱结点的指针域.因此,在双向链表中的结点都有两个指针域,一个指向前驱, ...

  6. 【Java】 大话数据结构(1) 线性表之顺序存储结构

     本文根据<大话数据结构>一书,实现了Java版的顺序存储结构. 顺序存储结构指的是用一段地址连续的存储单元一次存储线性表的数据元素,一般用一维数组来实现. 书中的线性表抽象数据类型定义如 ...

  7. 【Java】 大话数据结构(2) 线性表之单链表

    本文根据<大话数据结构>一书,实现了Java版的单链表. 每个结点中只包含一个指针域的链表,称为单链表. 单链表的结构如图所示: 单链表与顺序存储结构的对比: 实现程序: package ...

  8. 【Java】 大话数据结构(3) 线性表之静态链表

    本文根据<大话数据结构>一书,实现了Java版的静态链表. 用数组描述的链表,称为静态链表. 数组元素由两个数据域data和cur组成:data存放数据元素:cur相当于单链表中的next ...

  9. 【Java】 大话数据结构(5) 线性表之双向链表

    本文根据<大话数据结构>一书,实现了Java版的双向链表. 在每个数据结点中都有两个指针,分别指向直接后继和直接前驱,这样的链表称为双向链表. 双向链表的结构如图所示: 查找元素可以根据元 ...

随机推荐

  1. git merge 合并分支

    git merge 用来做分支合并,将其他分支中的内容合并到当前分支中.比如分支结构如下: master / C0 ---- C1 ---- C2 ---- C4 \ C3 ---- C5 \ iss ...

  2. [转]ASP.NET Web.Config 读写辅助类

    using System; using System.Configuration; using System.Web; using System.Web.Configuration; namespac ...

  3. oracle中merge的详解

    Oracle在9i引入了merge命令, 通过这个merge你能够在一个SQL语句中对一个表同时执行inserts和updates操作. 当然是update还是insert是依据于你的指定的条件判断的 ...

  4. hdu 2444 二分图判断与最大匹配

    题意:有n个学生,有m对人是认识的,每一对认识的人能分到一间房,问能否把n个学生分成两部分,每部分内的学生互不认识,而两部分之间的学生认识.如果可以分成两部分,就算出房间最多需要多少间,否则就输出No ...

  5. C/C++函数使用

    1 memset 将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针. 函数介绍 ...

  6. 关于android LinearLayout的比例布局(转载)

    关于android LinearLayout的比例布局,主要有以下三个属性需要设置: 1,android:layout_width,android:layout_height,android:layo ...

  7. LoadRunner之自定义HTTP请求

    LoadRunner之自定义HTTP请求 性能测试开发脚本时使用的都是同样的模式.对在性能测试规划时指定的典型业务逻辑场景进行录制,形成基本的脚本骨架. 录制脚本后需要对脚本进行编辑,以满足性能测试需 ...

  8. 寒假 D3 D Modular Inverse

    Modular Inverse Time Limit: 2 Seconds                                     Memory Limit: 65536 KB     ...

  9. BZOJ3571 : [Hnoi2014]画框

    题目是要求最小乘积最小权匹配, 将一种方案看做一个二维点(x,y),x=a值的和,y=b值的和,所有方案中只有在下凸壳上的点才有可能成为最优解 首先要求出两端的方案l,r两个点 l就是a值的和最小的方 ...

  10. 转:JQuery中$.ajax()方法参数详解

    url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...