Java数据结构与算法(第四章栈和队列)

本章涉及的三种数据存储类型:栈、队列和优先级队列。

不同类型的结构

程序员的工具

数组是已经介绍过的数据存储结构,和其他结构(链表、树等等)一样,都适用于数据应用中作数据记录。

然而,本章要讲解的是数据结构和算法更多的是作为程序员的工具来运用。它们组要作为构思算法的辅助工具,而不是完全的数据存储工具。这些数据结构的生命周期比那些数据库类型的结构要短的多。在程序操作执行期间它们才被创建,通常它们去执行某项特殊的任务,当完成之后,它们就被销毁。

受限访问

在数组中,只要知道下标就可以访问数据项。或顺序访问等。

而本章的数据结构中,访问时受限制的,即在特定时刻只有一个数据项可以被读取或者被删除(除非“作弊”);

这些结构接口的设计增强了这种受限访问。访问其他数据项(理论上)是不允许的。

更加抽象

栈、队列和优先级队列是比数组和其他数据存储结构更为抽象的结构。主要通过接口对栈、队列和优先级队列进行定义,这些接口表明通过他们可以完成的操作,而它们的主要实现机制对用户来说是不可见的。

例如,栈的主要机制可以用数组来实现,但它也可以用链表了实现。优先级队列的内部实现可以用数组或一种特别的书———堆来实现。

栈只允许访问一个数据项:即最后插入的数据项。移除这个数据项后才能访问倒数第二个插入的数据,以此类推。

栈的Java代码

public class Stack {
    private int maxSize;
    private long[] stackArray;
    private int top;
    public Stack(int s){
        maxSize = s;
        stackArray = new long[maxSize];
        top=-1;
    }
    public void push(long j){
        stackArray[++top] = j;
    }
    public long pop(){
        return stackArray[top--];
    }
    public long peek(){
        return stackArray[top];
    }
    public boolean isEmpty(){
        return (top==-1);
    }
    public boolean isFull(){
        return top==maxSize-1;
    }
}
public static void main(String[] args) {
    Stack theStack = new Stack(10);
    theStack.push(10);
    theStack.push(20);
    theStack.push(30);
    theStack.push(40);
    while(!theStack.isEmpty()){
        long value = theStack.pop();
        System.out.print(value);
        System.out.print("    ");
    }
}
//输出:
40	30	20	10

栈的效率

栈操作所耗的时间不依赖与栈中数据项的个数,因此操作时间很短。栈不需要比较和移动操作。

队     列

“队列”(queue)这个单词是英国人说的“排”(line)(一种等待服务的方式)。

队列是一种数据结构,有点类似栈,只是在队列中第一个插入的数据项也会最先被移除(先进先出,FIFO),而在栈中,最后插入的数据项最先移除。

队列的Java代码

public class Queue {
    private int maxSize;
    private long[] queueArray;
    private int front;
    private int rear;
    private int nItems;
    
    public Queue(int s){
        maxSize = s;
        queueArray = new long[maxSize];
        front = 0;
        rear = -1;
        nItems = 0;
    }
    public void insert(long j){
        if(rear == maxSize-1)
            rear = -1;
        queueArray[++rear]=j;
        nItems++;
    }
    public long remove(){
        long temp = queueArray[front++];
        if(front==maxSize)
            front = 0;
        nItems--;
        return temp;
    }
    public long peekfront(){
        return queueArray[front];
    }
    public boolean isEmpty(){
        return nItems ==0;
    }
    public boolean isFull(){
        return nItems == maxSize;
    }
    public int size(){
        return nItems;
    }
}
public static void main(String[] args) {
    Queue theQueue = new Queue(5);
    
    theQueue.insert(10);
    theQueue.insert(20);
    theQueue.insert(30);
    theQueue.insert(40);
    
    theQueue.remove();
    theQueue.remove();
    theQueue.remove();
    
    theQueue.insert(50);
    theQueue.insert(60);
    theQueue.insert(70);
    theQueue.insert(80);
    theQueue.insert(90);
    theQueue.insert(100);
    
    while(!theQueue.isEmpty()){
        long n = theQueue.remove();
        System.out.print(n);
        System.out.print(" ");
    }
    System.out.println("");
}

队列的效率

和栈一样,队列中插入数据项和移除数据项的时间复杂度均为O(1)。

双端队列

双端队列,就是一个两端都是结尾的队列。队列的 每一端都可以插入数据项和移除数据项。这些方法可以叫做insertLeft()和insertRight(),以及removeLeft()和removeRight()。

双端队列与栈或队列相比,是一种多用途的数据结构,在容器类库中有时会用双端队列来提供栈和队列的两种功能。但是,双端队列不像栈和队列那么常用。。。。。。。

优先级队列

优先级队列是比栈和队列更专用的数据结构。但它在很多的情况下都很有用。像普通队列一样,优先级队列有一个对头和一个队尾,并且也是从头移除数据项。不过在优先级队列中,数据项按关键字的值有序,这样关键字最小的数据项(或者在某些实现中关键字最大的数据项)总是在队头。数据项插入的时候会按照顺序插入到合适的位置以确保队列的顺序。

优先级队列Java代码

public class PriorityQueue {
    private int maxSize;
    private long[] queueArray;
    private int nItems;
    
    public PriorityQueue(int s){
        maxSize = s;
        queueArray = new long[maxSize];
        nItems = 0;
    }
    
    public void inser(long item) {
        int i;
        if(nItems==0)
            queueArray[nItems++] = item;
        else
        {
            for (i = nItems-1; i>=0; i--) {
                if(item>queueArray[i])
                    queueArray[i+1] = queueArray[i];
                else
                    break;
            }
            queueArray[i+1] = item;
            nItems++;
        }
    }
    
    public long remove(){
        return queueArray[--nItems];
    }
    
    public long meekMin(){
        return queueArray[nItems-1];
    }
    
    public boolean isEmpty(){
        return nItems
            ==0;
    }

    public boolean isFull(){
        return nItems==maxSize;
    }
}
public static void main(String[] args) {
    PriorityQueue queue = new PriorityQueue(5);
    
    queue.inser(30);
    queue.inser(50);
    queue.inser(10);
    queue.inser(40);
    queue.inser(20);
    
    while(!queue.isEmpty()){
        long item = queue.remove();
        System.out.print(item);
        System.out.print(" ");
    }
    System.out.println("");
}
//输出:10 20 30 40 50

在main()方法中随机插入5个数据项,随后移除并显示它们。最小的数据项总是最先移除,所以输出是:

10 20 30 40 50

优先级队列的效率

在本章实现的优先级队列中,插入操作需要O(N)的时间,而删除则需要O(1)的时间。

解析算术表达式

后缀表达法

日常算术表达式是将操作符(operator)(+,-,*,/)放在两个操作数(operands)(数字或代表数字的字母)之间的。因为操作符写在操作数的中间,所以把这表写法成为中缀表达法。

在后缀表达式中【也称为波兰逆序表达式(Reverse Polish Natation),或者RPN】,它是由以为波兰数学家发明的,操作符跟在两个操作数的后面。这样,A+B就成为AB+,A/B成为AB/。更复杂的如下表:

中缀表达式 后缀表达式
A+B-C AB+C-
A*B/C AB*C/
A+B*C ABC*+
A*B+C AB*C+
A*(B+C) ABC+*
A*B+C*D AB*CD*+
(A+B)*(C-D) AB+CD-*
((A+B)*C)-D AB+C*D-
A+B(C-D/(E+F)) ABCDEF+/-*+

后缀表达式求职。。。。。

小    结

  • 栈、队列和优先级队列是经常用于简化某些程序操作的数据结构。
  • 在这些数据结构中,只有一个数据项可以被访问。
  • 栈允许访问最后一个插入的数据项。
  • 栈中重要的操作是在栈顶插入(压入)一个数据项,以及从栈顶移除(弹出)一个数据项。
  • 队列只允许访问第一个插入的数据项。
  • 队列的重要操作是在队尾插入数据项和在队头移除数据项。
  • 队列可以实现为循环队列,它基于数组,数组下标可以从数组末端回绕到数组的开始位置。
  • 优先级队列允许访问最小(或者有时是最大)的数据项。
  • 优先级队列的重要操作是有序地插入新数据项和移除关键字最小的数据项。
  • 这些数据结构可以用数组实现,也可以用其他机制(例如链表)来实现。
  • 普通算术表达式是用中缀表达法表示的,这种命名的原因是操作符写在两个操作的中间。
  • 在后缀表达法中,操作符跟在两个操作数的后面。
  • 算术表达式求值通常都是先转换成后缀表达式,然后再求后缀表达式的值。
  • 在中缀表达式转换到后缀表达式以及求后缀表达式的值过程里,栈都是很有用的工具。
时间: 2024-12-15 07:15:30

Java数据结构与算法(第四章栈和队列)的相关文章

java数据结构和算法-----第四章

栈和队列 栈(后进先出) 栈,只允许访问一个数据项:即最后插入的数据项. 栈可以用来检查括号的匹配问题和解析数学表达式,类似于在编译原理中的使用. 该图片的操作实际上归纳起来:1.读到左分隔符入栈,2.读到右分隔符就和从栈顶弹出来的左分割符匹配,匹配成功,就正常进行. 3.读到一般的字母字符,就过滤掉.栈的入栈和出栈的时间复杂度都是O(1) 队列(先进先出) 队列的主要有以下几种方法:insert(),remove(),peek(),isFull(),isEmpty()和size()

Java数据结构与算法(第一章综述)

数据结构和算法能起到什么作用? 数据结构是对在计算机内存中(有时在磁盘中)的数据的一种安排.数据结果包括数组.链表.栈.二叉树.哈希表等等.算法对这些结构中的数据进行各种处理,例如,查找一条特殊的数据项或对数据进行排序. 可用于下面三类情况: 现实数据存储 程序员的工具 建模 数据结构的特性: 数据结构 优点 缺点 数组 插入快,如果知道下标,可以非常快地存取 查找慢,删除慢,大小固定 有序数组 比无序的数组查找快 删除和插入慢,大小固定 栈 提供后进先出的方式存取 存取其他项很慢 队列 提供先

数据结构与算法系列研究二——栈和队列

栈和队列的相关问题分析 一.栈和队列定义 栈和队列是两种重要的数据结构.从结构特性角度看,栈和队列也是线性表,其特殊性在于它们的基本操作是线性表的子集,是操作受限的线性表,可称为限定性的数据结构:从数据类型角度看,其操作规则与线性表大不相同,是完全不同于线性表的抽象数据类型.                    图1 栈的结构                                                 图2 队列的结构   1.1.栈是限定在表的一端进行插入和删除操作的线性

数据结构期末复习第三章栈和队列

第三章:栈和队列 栈的特性:后进先出(LIFO) 1.  输入序列为ABC,可以变为CBA时,经过的栈操作为( B )A. push, pop, push, pop, push, popB. push, push, push, pop, pop, popC. push, push, pop, pop, push, popD. push, pop, push, push, pop, pop 解析: ABC经过push,push,push操作后,从栈顶到栈底元素为CBA,经过pop,pop,pop出

第四章 栈与队列

一.栈的定义 栈(stack)是限定尽在表尾进行插入和删除操作的线性表. 我们把允许插入和删除的一端成为栈顶(top),另一端成为栈底(bottom),不含任何数据元素的栈称为空栈.栈又称为后进先出(LIFO)的线性表. 图示出栈入栈操作: 二.栈的抽象数据类型 图示栈的各项操作: 由于栈本身就是一个线性表,那么上一章我们讨论了线性表的顺序存储和链式存储,对于栈来说也是同样适用的. 三.栈的顺序存储结构及实现 来看一下栈的结构定义: 若存储栈的长度为StackSize,则栈顶位置top必须小于S

Java数据结构与算法(第二章数组)

数组是应用最广泛的数据存储结构.它被植入到大部分编程语言中. Java中数组的基础知识     创建数组 在Java中把它们当作对象来对待,因此在创建数组是必须使用new操作符:     int[] intArray;            //defines a reference to an array     ingArray = new int[100];    //creates the array, and                                  //set

《大话数据结构》--- 第四章 栈与队列

栈(Stack)是限定仅在表尾进行插入和删除操作的线性表. 把允许插入和删除的一端称为栈顶,另一端称为栈底,不含任何数据元素的栈称为空栈.栈又称为后进先出的线性表,简称LIFO结构. 栈的插入操作,叫做进栈,也称压栈.入栈. 栈的删除操作,叫做出栈,也称弹栈. 当两个栈一个占用内存可能太大 但内容较少 另一个占用内存可能有剩余 可以考虑使用一个数组来存两个栈,一个底端从下标0开始,另一个底端从下标n-1开始,只要两个栈不碰头 就可以实现空间的有效利用. 栈的链式存储结构称为栈链. 如果栈的使用过

JavaScript数据结构与算法——第三章 栈

栈:后进先出.栈顶在最后,栈底在最前.新添加的元素和待删除的元素抖保存在栈的末尾. 创建一个栈: function Stack() { var items = []; /*用数组保存栈里的元素*/ this.push = function(e) { items.push(e); } this.pop = function() { return items.pop(); } this.peek = function() { return items[length - 1]; } this.isEm

第四章 栈与队列2 (对列)

4.2 队列 4.2.1 队列的定义 队列简称队,它通栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除.在队列中把插入数据元素的一端称为队尾(rear),删除元素的一端称为队首(front).向队尾插入元素称为进队或入队.从队列中删除元素称为离队或出队. 队列是先进先出表(First In First Out,FIFO). 队列的接口Queue: 1 package com.datastructure.chapter04.interfaces; 2 3