`

重走算法路之循环队列的实现

 
阅读更多

        前天写了栈的实现,今天到队列了,好像明天要期中考试,还是三科,次奥,考吧考吧,五一三天已经贡献给你们了,考成什么样我也认了,毕竟智商在这里。说好的一天来一发,不要说我水,其实我还真的是水,上个学期数据结构课打酱油,这个学期又自己抱本书从第一页开始恭恭敬敬地学,不敢跳过一个字。估计是脑子里面灌浆了。上学期不认真。前车之鉴,希望筒子们好好的把数据结构学好。希望老夫子还为时不晚。

        队列和栈一样也是一种很基本的数据结构,队列的用途很多,下面是两个例子。

        第一个例子就是CPU资源的竞争问题。在具有多个终端的计算机系统中,有多个用户需要使用CPU各自运行自己的程序,   它们分别通过各自终端向操作系统提出使用CPU的请求,操作系统按照每个请求在时间上的先后顺序,将其排成一个队列,每次把CPU分配给队头用户使用,当相应的程序运行结束,则令其出队,再把CPU分配给新的队头用户,直到所有用户任务处理完毕。

         第二个例子就是主机与外部设备之间速度不匹配的问题。以主机和打印机为例来说明,主机输出数据给打印机打印 ,主机输出数据的速度比打印机打印的速度要快得多,若直接把输出的数据送给打印机打印,由于速度不匹配,显然是不行的。所以解决的方法是设置一个打印数据缓冲区,主机把要打印输出的数据依此写如到这个缓冲区中,写满后就暂停输出,继而去做其它的事情,打印机就从缓冲区中按照先进先出的原则依次取出数据并打印,打印完后再向主机发出请求,主机接到请求后再向缓冲区写入打印数据,这样利用队列既保证了打印数据的正确,又使主机提高了效率。

        通过上面的两个例子我们知道队列和栈之间的本质的区别了。栈是遵循先进后出,而队列则是遵循先进先出。由于它的先进先出,导致当队头的元素出来之后,队头的指针会上移,往队尾插入元素的时候队尾的指针也是往上移,这个和我们平时的生活经验可能不一样,以我们平时的生活经验,排队买票,队头的人买完票之后,后面的人会向前补上来,这一补可是所有的人都要往前移动一个位置,这在计算机的队列中就相当于要后面的所有元素都要往前进一个位置,这个开销是很大的,所以,计算机中的队列没有采取这样的方法。但是这样之后另外一个问题又出来了,当 把队头的元素移走之后,队头上移,我们知道,队列插入元素是从后面插入的,这就造成了队头前面的内存空出来了,而且还不能用了,因为我们不能把元素从队头插进去。于是乎,聪明的人们想到了循环队列这种东西。当队尾插不进去,队头前面又还有空位的时候,就把队尾下调到队头前面的位置,但记住他还是队尾,如此下去,就不会担心内存的浪费了下面用图来解释一下:


 



 

通过上面的两个图,应该能知道循环队列是怎么实现的了,就多了一个判断,哥哥画图可画了一个多小时。。。。

 

下面贴出代码,注释详细:

package 环形数组队列;

public class CricleQueue {
	/*
	 * 对列的长度
	 */
	private int maxSize;
	
	/*
	 * 队列数组
	 */
	private long[] queueArray;
	
	/*
	 * 头下标(指针)
	 */
	private int front;
	
	/*
	 * 尾下标(指针)
	 */
	private int rear;
	
	/*
	 * 队列中元素的个数
	 */
	private int nElement;
	
	/*
	 * 构造方法,初始化各种数据
	 */
	public CricleQueue(int maxSize) {
		this.maxSize = maxSize;
		queueArray = new long[maxSize];
		rear = -1;
		front = 0;
		nElement = 0;
	}
	
	/*
	 * 在队列的尾部插入一个元素
	 */
	public void insert(long value) {
		if(rear==maxSize-1){
			rear = -1;
		}
		queueArray[++rear] = value;
		nElement++;
	}
	
	/*
	 * 删除队头的元素
	 */
	public long remove() {
		long temp = queueArray[front++];
		if(front==maxSize) {
			front = 0;
		}
		nElement--;
		return temp;
	}
	
	
	/*
	 * 判断队列是否为空
	 */
	public boolean isEmpty() {
		return nElement==0;
	}
	
	/*
	 * 判断队列是否为满
	 */
	public boolean isFull() {
		return nElement==maxSize;
	}
	
	/*
	 * 查看队头元素
	 */
	
	public long peekF() {
		return queueArray[front];
	}
	
	/*
	 * 查看元素个数
	 */
	
	public int qSize() {
		return nElement;
	}
	
	
	public static void main(String[] args) {
		CricleQueue cq = new CricleQueue(5);
		
		System.out.println("队列是否为空:"+cq.isEmpty());
		
		//插入元素
		cq.insert(1);
		cq.insert(2);
		cq.insert(3);
		System.out.println("队列是否满了:"+cq.isFull());
		cq.insert(4);
		cq.insert(5);
		System.out.println("队列中元素个数:"+cq.qSize());
		
		System.out.println("队列是否满了:"+cq.isFull());
		System.out.println("对头的元素为:"+cq.peekF());
		
		//移除两个元素
		cq.remove();
		cq.remove();
		System.out.println("队列中元素个数:"+cq.qSize());
	
		System.out.println("对头的元素为:"+cq.peekF());
		
		//插入两个元素
		cq.insert(6);
		cq.insert(7);
		System.out.println("队列中元素个数:"+cq.qSize());
		
		System.out.println("队列是否满了:"+cq.isFull());
		
		//移除四个元素
		cq.remove();
		cq.remove();
		cq.remove();
		cq.remove();
		System.out.println("队列中元素个数:"+cq.qSize());
		System.out.println("对头的元素为:"+cq.peekF());
		
	}
}

 

   输出结果:

 

队列是否为空:true
队列是否满了:false
队列中元素个数:5
队列是否满了:true
对头的元素为:1
队列中元素个数:3
对头的元素为:3
队列中元素个数:5
队列是否满了:true
队列中元素个数:1
对头的元素为:7

 

    就这样,队列的内存就不会被浪费掉了,只要里面有空的位置你就可以插入元素。

         

       

 

1
0
分享到:
评论

相关推荐

    分支限界算法 01背包问题

    01背包问题是一个经典的组合优化问题,目标是确定如何在容量有限的背包中放入物品以最大化总价值,其中每种物品都有一个重量和一个价值,且物品只能被完全取走,不能分割。 首先,我们需要理解分支限界法的基本框架...

    算法解析ACM

    此类问题可以通过构建有向图,并应用Bellman-Ford算法来检测负权重循环。 #### 排序与检索算法 排序和检索是计算机科学中最基本的操作之一,对于提高程序效率至关重要。 **案例分析:Pku1723—SOLDIERS** 题目...

    Java常见100多种算法大全

    这份资源提供了超过100种不同的Java实现,旨在帮助学习者深入理解算法原理,并提高编程技能。以下将详细解释其中涉及的一些重要知识点: 1. **排序算法**: - **冒泡排序**:通过相邻元素比较并交换位置,逐步将...

    精心整理史上最全的数据结构flash演示动画,共5个版本,祝大家考研成功!

    \数据结构flash演示\版本1\3-3-13循环队列.swf \数据结构flash演示\版本1\3-3-1栈的应用举例-走迷宫-有解.swf \数据结构flash演示\版本1\3-3-2栈的应用举例-走迷宫-无解.swf \数据结构flash演示\版本1\3-3-4后缀...

    图的深度广度遍历程序C语言实现

    3. 定义一个循环,每次从队列中取出一个顶点,标记为已访问,然后将其邻接点加入队列(如果它们尚未被访问)。 在"Adjacency Multilist"这个文件中,应该包含了实现这些功能的代码。通过阅读和理解这段代码,你可以...

    CCF PTA编程培训师资认证考试-P试卷-C++

    - **数组处理:**使用一个整型数组存储输入的10个整数,并利用循环遍历数组以实现后续操作。 - **排序算法:**根据题目要求,需要将数组分为奇数和偶数两部分。对于奇数部分,可以使用任何一种排序算法(如快速排序...

    CC++ 技术面试基础知识总结,包括语言、程序库、数据结构、算法、系统、网络、链接装载库等知识及面试经验

    - **链接过程**:编译、汇编、链接三步走,理解符号解析和重定位。 - **装载过程**:了解装载器如何将可执行文件映射到内存中。 面试时,不仅需要理解这些概念,还需要能够分析问题、设计解决方案,并能写出高效...

    基于JAVA的动画迷宫老鼠课程设计

    这些算法可以用来寻找从起点到终点的路径,同时确保老鼠在迷宫中不走回头路。 6. **数据结构**:在实现迷宫算法时,可能需要使用到数据结构,如栈(用于DFS)或队列(用于BFS)。另外,迷宫本身可以用二维数组或者...

    走迷宫游戏代码(c++开发)

    走迷宫游戏是一种经典的计算机程序设计问题,它通常涉及到路径搜索算法、图形用户界面(GUI)设计以及事件处理。在C++中实现这样的游戏,我们可以从以下几个方面来深入理解相关知识点: 1. **C++基础知识**:C++是...

    java 小游戏象棋

    开发者可能需要考虑减少界面重绘次数,优化搜索算法效率,以及合理使用多线程来提高游戏流畅度。 通过以上技术点的实现,一个基本的Java小游戏象棋就可以开发完成。这样的项目不仅有助于巩固Java编程基础,还可以...

    《计算机操作系统》期末复习指导

    先进先出算法(FIFO)、循环检测法、最近最少使用页面先淘汰(LRU)、最不经常使用的页面先淘汰(LFU)、最近没有使用页面先淘汰(NUR)、最优淘汰算法(OPT)等。 (4)页式存储管理的优、缺点 优点: ...

    java常见经典小游戏源码

    - **动画效果**:消除匹配对时的动画效果,可能通过定时器和组件重绘实现。 4. **Java五子棋.rar**: - **棋盘逻辑**:实现棋盘上的落子规则,检查赢棋条件(五子连珠)。 - **游戏AI**:可能包含简单的AI对手,...

    VC编的五子棋程序源代码

    程序通过消息循环(`Run`函数)不断检查队列,调用相应处理函数,即消息映射函数,如`ON_WM_LBUTTONDOWN`等,处理这些事件。 三、棋盘逻辑与算法 1. 棋盘表示:通常使用二维数组来表示棋盘,每个元素代表一个格子,...

    电子技术基础复习题 (2).doc

    本复习题主要涵盖了电子技术中的数据结构、算法设计以及与之相关的计算机科学基础知识。以下是对各个题目涉及知识点的详细解析: 1. 删除单链表中重复结点:此题考察链表操作和算法设计。首先,我们需要遍历链表,...

    Visual C++写的跳棋游戏源码

    此外,开发者可能会使用递归或循环来实现棋子的连续跳跃功能,这需要对栈或队列等数据结构有扎实的理解。 图形界面的绘制通常涉及CDC类,它提供了基本的绘图操作,如画线、填充颜色等。开发者可能使用CDC的成员函数...

    美团校园招聘历年经典面试题汇总:后台开发岗1

    9. **拥塞控制**:网络拥塞控制通过减少发送速率来防止过多的数据同时在网络中传输,常见的算法有慢启动、拥塞避免、快速重传和快速恢复等。 10. **JVM的GC内容**:Java虚拟机的垃圾收集主要包括新生代、老年代的...

    c语言笔试题答案.doc

    避免在循环体内做无谓的判断语句,将循环语句置于判读语句的代码块之中 * 设数组 a[5]={10,20,30,40,50};已知指针p 指向 a[1];则表示式*++p 的值是( A .20 ) * 有以下程序段,执行后,mul 的值为( B ) 通过...

Global site tag (gtag.js) - Google Analytics