Java数组实现顺序栈与队列

栈和队列是两种特殊的线性表,他们的逻辑结构和线性表相同,只是其运算规则较线性表有更多的限制。本文介绍如何使用顺序栈、顺序队列和优先队列以及使用的规则和要领。
技术要点
数组实现顺序栈与队列的技术要点如下:

  • 栈是一种数据结构,限制仅在表的一端进行插入和删除运算的线性表。其数据项的插入和删除(获取)都只能在成为栈顶的一端完成。因为最后插入的数据项就是最先要删除的数据项。当数据项中没有元素时称为空栈。栈为后进先出(Last In First Out)的线性表,简称LIFO表。
  • 顺序栈:栈的顺序存储结构,它是运算受限的线性表。顺序栈的元素用向量存放。栈底的位置是固定不变的,可设置在向量两端的任意一个端点。栈顶位置是随着进栈和出栈操作而变化的,用一个整形变量top(栈顶指针)来表示。
  • 当程序同时使用两个栈时,可以将两个栈的栈底设在向量空间的两端,让两个栈各自向中间延伸。当一个栈里的元素较多,超过向量空间的一半时,只要另一个栈的元素不多,那么前者就可以占用后者的部分存储空间。只有当整个向量空间被两个栈占满时,才会发生上溢。因此,两个栈共享一个长度为m的向量空间和两个栈分别占用两个长度为[m/2] 和[m/2]的向量空间比较,前者发生上溢的概率要比后者小得多。
  • 队列是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。允许删除的一端称为队头,允许插入的一端称为队尾,当队列中没有元素时称为空队列。队列可称为先进先出(First In First Out)的线性表,简称FIFO表。
  • 顺序队列:队列的顺序存储结构,实际是运算受限的线性表。和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素。由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,他们的初值在队列初始化时均应置为0。
    实现步骤
    1. 新建一个类名为TextStackAndQueue.java。
    2. 代码如下表示:
package com.sunyueqing.s1;

class Stack {                       //实现顺序栈的类
    long stackArray[];             //栈数组
    int size;
    int top;

    public Stack(int size) {                   //构造方法初始化大小为size的栈
        this.size = size;
        this.stackArray = new long[size];
        this.top = -1;
    }

    public long pop() {                        //出栈操作
        return stackArray[top--];
    }

    public void push(long value) {             //入栈操作
        stackArray[++top] = value;
    }

    public boolean isEmpty() {                 //判断栈是否为空
        return top == -1;
    }

    public boolean isFull() {                  //判断栈是否已满
        return top == size - 1;
    }

    public long peek() {           //取栈顶元素
        return stackArray[top];
    }
}

class Queue {                              //实现顺序队列的类
    private long queueArray[];          //队列数组
    private int front;                   //队列的前端下标
    private int rear;                    //队列的尾端下标
    private int size;                    //队列的大小
    private int count;                   //队列中元素的个数

    public Queue(int size) {               //构造方法初始化大小为size的队列
        this.queueArray = new long[size];
        this.size = size;
        this.front = 0;
        this.rear = -1;
        this.count = 0;
    }

    public void insert(long value) {         //插入操作
        if (rear == size - 1)                    //队列已满
            rear = -1;
        queueArray[++rear] = value;
        count++;
    }

    public long remove() {                  //删除操作
        long temp = queueArray[front++];
        if (front == size)
            front = 0;
        count--;
        return temp;
    }

    public long peakFront() {              //返回队列的第一个元素
        return queueArray[front];
    }

    public boolean isEmpty() {                 //判断是否为空
        return count == 0;
    }

    public boolean isFull() {                  //判断是否已满
        return count == size;
    }

    public int Count() {                         //返回队列中元素的个数
        return count;
    }

    public void print() {                         //输出队列元素
        for (int i = front; i < front + count; i++) {
            System.out.print(queueArray[i] + "\t");
        }
        System.out.println();
    }
}

class PriorityQueue {                           //实现优先队列的类
    private int count;                       //队列中元素的个数
    private long priorityArray[];          //队列数组
    private int size;                        //队列的大小

    public PriorityQueue(int size) {           //构造方法初始化大小为size的队列
        this.size = size;
        this.priorityArray = new long[size];
        this.count = 0;
    }

    public void insert(long value) {       //插入操作
        int i;
        if (count == 0)
            priorityArray[count++] = value;
        else {
            for (i = count - 1; i >= 0; i--) {                        //循环找到比插入值大的位置
                if (value < priorityArray[i]) {
                    priorityArray[i + 1] = priorityArray[i];           //依次移动位置
                } else
                    break;
            }
            priorityArray[i + 1] = value;                //插入值放到指定位置
            count++;
        }
    }

    public long remove() {               //删除操作
        return priorityArray[--count];
    }

    public boolean isEmpty() {                 //判断是否为空
        return count == 0;
    }

    public boolean isFull() {                  //判断是否已满
        return count == size;
    }

    public void print() {                         //输出队列元素
        for (int i = 0; i < count; i++) {
            System.out.print(priorityArray[i] + "\t");
        }
        System.out.println();
    }
}

public class TextStackAndQueue {          //操作顺序栈与队列的类
    public static void main(String[] args) {   //java程序主入口处
        System.out.println("1.数组实现顺序栈");
        Stack stack = new Stack(6);         //实例化顺序栈,栈的大小为6
        while (!stack.isFull()) {                //只要栈不满就循环
            long r = (long) (Math.random() * 20);
            stack.push(r);                       //入栈
            System.out.print(r + "\t");
        }
        System.out.println();
        while (!stack.isEmpty()) {               //只要栈不空就循环
            long value = stack.pop();            //获得栈顶元素
            System.out.print(value + "\t");
        }
        System.out.println();
        System.out.println("--------------------------------------------");
        System.out.println("2.数组实习顺序队列");
        Queue queue = new Queue(6);         //实例化顺序队列,队列的大小为6
        while (!queue.isFull()) {               //只要队列不满就循环
            long value = (long) (Math.random() * 20);
            queue.insert(value);                 //元素插入队列
        }
        queue.print();                            //输出队列元素
        while (!queue.isEmpty()) {                //只要栈不空就循环
            queue.remove();                       //元素移除
            queue.print();                        //输出队列元素
        }
        queue.print();                            //输出队列元素
        System.out.println(queue.isEmpty());     //队列是否为空?
        System.out.println("--------------------------------------------");
        System.out.println("3.数组实现优先队列");
        PriorityQueue priority = new PriorityQueue(6);      //实例化顺序队列,队列的大小为6
        while (!priority.isFull()) {                             //只要队列不满就循环
            long value = (long) (Math.random() * 20);
            priority.insert(value);                             //元素插入队列
        }
        priority.print();                                       //输出队列元素
    }
}

3.运行结果
这里写图片描述
源程序解释

  • Stack类实现顺序栈,包括入栈、出栈、置栈空、判断栈是否为空以及判断栈是否已满和取栈内的元素。入栈的push()方法需要将栈顶top加1,需要注意的是,top=size-1表示栈满,当栈满时再做入栈运算产生空间溢出的现象,简称“上溢”。出栈的pop()方法需要将栈顶top减1,top<0表示空栈。当栈空时,做出栈运算产生溢出现象,简称“下溢”。当取栈内的元素时,由于栈是先进后出的,则取到的元素是最后放入的元素。
  • Queue类实现顺序队列,包括入队、出队、置空队列、判断队列是否为空以及判断队列是否已满和取队列中的元素。入队的insert()方法将新元素插入到rear所指的位置,然后rear加1,需要注意的是,rear=size-1表示队列已满,当队列满时,做进栈运算产生空间溢出的现象,简称“真上溢”。当队列中实际的元素个数远远小于向量空间的规模时,也可以由于尾指针已超越向量空间的上界而不能做入队操作,该现象称为“假上溢”。出队的remove()方法删去front所指的元素,然后将front加1并返回被删除的元素。当count为空时,做出队运算产生溢出,称为“下溢”。“下溢”常用作程序控制转移的条件。当取队列的元素时,由于队列是先进先出的,则取到的元素是最先放入的元素。
  • PriorityQueue类实现优化队列,对队列中的元素进行从小到大的排列。入队的insert()方法循环查找一个大于要插入元素的位置,当找到大于要插入的元素时就跳出,然后为要插入的元素留出位置,将要插入的元素保存到该位置。再根据队列元素是否为空和是否已满条件输出队列中已排序的元素,这样就实现了队列的优化操作。

猜你喜欢

转载自blog.csdn.net/sunyueqinghit/article/details/78159772