`

《Java数据结构和算法》学习笔记(3)——栈和队列

阅读更多
每篇笔记都会附上随书的Applet演示程序,有算法看不明白的,可以下载Applet运行起来(直接打开html文件即可),可以很容易地看清楚算法的每一步。

是一种先进后出(FILO)的线性数据结构,先进后出的意思就是……举个例子吧,我先把1放进一个栈里,再把2放进去,最后把3放进去,取出来的时候只能先得到3,再取能得到2,最后是1。栈一次只允许访问一个数据项(最顶端的那个),常用操作有入栈(push,把数据压入栈里)和出栈(pop,把顶端的数据从栈里弹出),peek用于查看栈顶数据。
下面是一个简单的栈的实现
package dsaa.array;

import java.util.EmptyStackException;

/**
 * @(#)Stack.java 2008-12-26 下午03:41:57
 * 
 * @author Qiu Maoyuan
 * Stack
 */
public class Stack<E> {

	private Object[] stackArray;
	private int topIndex = -1;
	private int size = 0;
	
	public Stack(){
		stackArray = new Object[10];
	}
	
	public Stack(int size){
		stackArray = new Object[size];
	}
	
	public void push(E value){
		ensureCapacity();
		stackArray[++topIndex] = value;
		size++;
	}
	
	@SuppressWarnings("unchecked")
	public E peek(){
		if(topIndex==-1)
			throw new EmptyStackException();
		return (E)stackArray[topIndex];
	}
	
	public E pop(){
		E value = peek();
		topIndex--;
		size--;
		return value;
	}
	
	public boolean isEmpty(){
		return size==0;
	}
	
	private void ensureCapacity() {
		if(size==stackArray.length){
			Object[] newArray = new Object[size * 3 / 2 + 1];
			System.arraycopy(stackArray, 0, newArray, 0, size);
			stackArray = newArray;
		}
	}
}

在给一个数组或者字符串进行反向排序的时候,栈是一个不错的工具:
		Stack<Character> stack = new Stack<Character>();
		String input = "hello stack!";
		for(int i=0; i<input.length(); i++)
			stack.push(input.charAt(i));
		
		StringBuilder buffer = new StringBuilder();
		while(!stack.isEmpty()){
			buffer.append(stack.pop().charValue());
		}
		String output = buffer.toString();
		System.out.println(output);

利用栈还可以实现回文判断、词法分析等功能。
显而易见,栈的push和pop操作的时间复杂度为O(1)。
队列

队列是一种先进先出(FIFO)的线性数据结构,常用操作有插入(insert)和删除(remove)。
一个简单的队列实现如下:
package dsaa.array;
/**
 * @(#)Queue.java 2008-12-27 上午01:21:46
 * 
 * @author Qiu Maoyuan
 * Queue
 */
public class Queue<E> {

	private Object[] queueArray;
	private int head = 0;
	private int tail = -1;
	
	public Queue(int size){
		queueArray = new Object[size];
	}

	@SuppressWarnings("unchecked")
	public E peek(){
		if(isEmpty())
			throw new IllegalStateException("Queue is empty");
		return (E)queueArray[head];
	}
	
	public void insert(E value){
		if(isFull())
			throw new IllegalStateException("Queue is full");
		queueArray[++tail] = value;
	}
	
	public E remove(){
		E value = peek();
		head++;
		return value;
	}
	
	public boolean isEmpty(){
		return tail - head == -1;
	}
	
	public boolean isFull(){
		return tail == queueArray.length-1;
	}
}

以上队列存在一个问题,队列满了以后,无论删除掉多少个数据项,甚至清空这个队列,仍然不能插入新的数据。其实有一种解决方法就是,在删除数据项的时候,后面的所有数据项都往前移动,但这样效率很低。
为了避免队列不满却不能插入新数据项的问题,可以让队头队尾指针绕回到数组开始的位置,这样的队列叫循环队列
改进后的代码如下:
package dsaa.array;
/**
 * @(#)Queue.java 2008-12-27 上午01:21:46
 * 
 * @author Qiu Maoyuan
 * Queue
 */
public class Queue<E> {

	private Object[] queueArray;
	private int head = 0;
	private int tail = -1;
	private int elementsCount = 0;
	
	public Queue(int size){
		queueArray = new Object[size];
	}

	@SuppressWarnings("unchecked")
	public E peek(){
		if(isEmpty())
			throw new IllegalStateException("Queue is empty");
		return (E)queueArray[head];
	}
	
	public void insert(E value){
		if(isFull())
			throw new IllegalStateException("Queue is full");
		if(tail == queueArray.length - 1){
			tail = 0;
			queueArray[tail] = value;
		}else{
			queueArray[++tail] = value;
		}
		elementsCount++;
	}
	
	public E remove(){
		E value = peek();
		if(head == queueArray.length - 1){
			head = 0;
		}else{
			head++;
		}
		elementsCount--;
		return value;
	}
	
	public boolean isEmpty(){
		return elementsCount == 0;
	}
	
	public boolean isFull(){
		return elementsCount == queueArray.length;
	}
}

队列的效率和栈一样,插入和删除数据项的时间复杂度均为O(1)。
还有一种队列叫做双端队列,顾名思义就是对两端都可以进行插入、删除操作的队列。如果封闭了其中一端,它就变成了一个栈;如果只允许一端插入,另一端删除,那它就成了一个普通队列。
优先级队列和普通队列的不同之处是:它在插入数据时是有序的。所以优先级队列的插入效率会比较低,时间复杂度为O(N),删除操作则为O(1)。
package dsaa.array;
/**
 * @(#)PriorityQueue.java 2008-12-27 下午01:03:01
 * 
 * @author Qiu Maoyuan
 * Priority Queue
 */
public class PriorityQueue {

	private int[] queueArray;
	private int head = -1;
	
	public PriorityQueue(int initialCapacity){
		queueArray = new int[initialCapacity];
	}
	
	public void insert(int value){
		if(isFull())
			throw new IllegalStateException("Queue is full");
		
		if (isEmpty()){
			queueArray[++head] = value;
		} else {
			int i=head;
			while (i>-1){
				if (queueArray[i]>value){
					queueArray[i + 1] = queueArray[i];
				} else {
					break;
				}
				i--;
			}
			queueArray[i + 1] = value;
			head++;
		}
	}
	
	public boolean isFull(){
		return head == queueArray.length - 1;
	}
	
	public boolean isEmpty(){
		return head == -1;
	}
	
	public int remove(){
		int value = peek();
		head--;
		return value;
	}
	
	public int peek(){
		if(isEmpty())
			throw new IllegalStateException("Queue is empty");
		return queueArray[head];
	}
}

分享到:
评论

相关推荐

    Java数据结构和算法-学习笔记

    ### Java数据结构与算法——学习笔记 #### 一、引言 在计算机科学领域,**数据结构**与**算法**是两个极其重要的概念。数据结构指的是数据的组织方式,而算法则是解决特定问题的一系列步骤。这两者是编程的基础,...

    《Java数据结构和算法》学习笔记(4)——链表

    链表常用于实现队列和栈,因为它们的操作特性(先进先出,后进先出)与链表的操作方式相吻合。此外,链表还可以用于实现哈希表的链地址法解决冲突。 8. 高级主题: 进一步学习,可以研究双向链表,它允许在节点的...

    数据结构与问题求解——java语言描述 源码

    数据结构主要包括数组、链表、栈、队列、树、图、集合和哈希表等。在Java中,这些数据结构可以通过内置类如ArrayList、LinkedList、Stack、Queue、HashSet和HashMap等来实现。例如,`Graph.java`文件很可能包含了图...

    哈尔滨工业大学《数据结构与算法》、《软件开发实践》作业及实验的Scheme解法。.zip

    在哈工大的《数据结构与算法》以及《软件开发实践》课程中,学生们通常会遇到一系列挑战性的作业和实验,这些任务旨在深化他们对数据结构和编程语言的理解。本资源包提供了一种独特的解决方案——Scheme语言的解法,...

    GitHub一战封神,字节跳动内部顶级数据结构刷题学习笔记根本停不下来(csdn)————程序.pdf

    标题和描述中提到的是一份源自字节跳动内部的数据结构刷题学习笔记,这份笔记在GitHub上引起广泛关注,被认为是一份有助于提升编程能力,尤其是对于准备字节跳动面试的程序员极具价值的资源。主要关注点在于各种排序...

    《数据结构——C++实现》(第二版)课本源代码.zip

    3. **栈**:是一种后进先出(LIFO)的数据结构,常用于表达式求值、函数调用和内存管理。C++标准库提供了`&lt;stack&gt;`容器适配器,可以方便地创建和操作栈。 4. **队列**:是先进先出(FIFO)的数据结构,常用于任务...

    福建省算法夏令营2018——课件

    2. **数据结构详解**:数据结构是算法的基础,课件可能涉及数组、链表、栈、队列、树(二叉树、平衡树如AVL和红黑树)、图、哈希表等。理解它们的性质和操作,对于优化算法至关重要。 3. **算法实例与应用**:通过...

    达内JAVA培训综合笔记

    随后,笔记转向数组和字符串的处理,这是编写Java程序中经常会使用到的数据结构。方法是Java程序中进行函数调用的基本单元,笔记中强调了方法的三要素,即方法签名、参数列表和返回类型。同时,也介绍了两种常见的...

    大一下Java大作业——双人联机小游戏森林冰火人.zip

    5. **数据结构与算法**:游戏中的物体位置、碰撞检测等都需要高效的数据结构(如数组、链表、队列、栈等)和算法(如搜索、排序、图遍历等)来处理。 6. **游戏逻辑**:实现游戏规则,如角色移动、碰撞检测、得分...

    从数据库自动导出表结构到docx(数据库验收文档).zip

    在描述中提到的“大学生 C/C++/JAVA/Python数据结构学习笔记和资料大全”,这是针对编程初学者的资源集合,涵盖了计算机科学中非常基础且重要的概念——数据结构。数据结构是计算机存储、组织数据的方式,包括数组、...

    基于SpringBoot的开源数据库表结构导出word文档工具.zip

    【描述】提到的"大学生 C/C++/JAVA/Python数据结构学习笔记和资料大全"则涵盖了计算机科学基础课程中的核心主题——数据结构。数据结构是计算机存储、组织数据的方式,它是算法分析的基础,直接影响程序的效率。C、...

    软件设计师—学习笔记.pdf

    数据结构与算法方面,涉及了数组、栈、队列、树与二叉树、图、查找与排序等数据结构和常见算法。此外,程序设计语言、计算机硬件基础、操作系统等也是必考内容。具体来说,操作系统包括文法、有限自动机、正规式、...

    Leetcode、剑指Offer——名企面试官精讲典型编程题.zip

    这本书系统地介绍了软件工程师面试中常遇到的算法和数据结构问题,涵盖了数组、链表、栈、队列、树等基础数据结构以及排序、查找、递归等基本算法。书中每个问题都配有详细的解题思路和代码实现,对于理解和应用这些...

    很好的计算机考研笔记

    3. **数据结构**:数组、链表、栈、队列、树、图等基本数据结构及其操作,以及排序和查找算法。 4. **算法**:贪心、动态规划、分治、回溯等算法思想,以及常用算法的分析与实现。 5. **操作系统**:进程管理、内存...

    手机游戏-海底探险 java手机游戏源码

    - **数据结构与算法**:如队列、栈、图等用于游戏逻辑和优化。 - **性能优化**:考虑内存管理、减少计算量、降低CPU和GPU负载等,确保游戏在手机上的流畅运行。 - **多线程**:可能用于处理游戏的并发操作,如背景...

    谷歌高畅、BAT霜神leetcode刷题笔记.zip

    4. 数据结构:包括数组、链表、栈、队列、树、哈希表等经典数据结构的应用。 5. 解题技巧:可能包含如何分析问题、设计解决方案、调试代码等方面的技巧。 【压缩包子文件的文件名称列表】:由于未提供具体的子...

    JAVA打飞机游戏毕业设计(源代码+l文).zip

    开发者需要编写复杂的算法来处理这些逻辑,这将涉及到数据结构(如数组、队列)和算法(如碰撞检测算法)的应用。 5. **文件操作与资源管理** 游戏可能需要保存和读取玩家的得分,或者加载音频、图像等资源。Java...

    MyJavaStudy:Java算法实践

    例如,`java.util`包中的`ArrayList`和`LinkedList`可以用来实现动态数组和链表,`PriorityQueue`可用于优先队列的构建,这些数据结构在许多算法中都是基础。同时,Java的异常处理机制和泛型特性使得代码更加健壮且...

    java8集合源码分析-LearningNotes:Java笔记

    算法和数据结构 排序算法、动态规划、递归、回溯法、贪心算法等 数组、栈、队列、链表、二分搜索树、集合、映射、优先队列、堆、线段树、Trie、并查集、AVL、红黑树、哈希表 数据处理典型案例,逐渐更新 :hot_...

Global site tag (gtag.js) - Google Analytics