普通队列,循环队列以及链队列的相关操作

队列,一种限定性的线性表。它只允许在表一端进行插入,而在表的另一端进行删除操作。

普通队列

这里写图片描述
基于此,我们定义了一个数据结构,包含首尾指针

class Queue{
    Object[] data;
    int front;
    int rear;
}

置空队列时 ,将rear=front=-1;

    public static Queue initEmptyQueue(){
        Queue queue=new Queue();
        queue.data=new Object[MAX_SIZE];
        queue.front=-1;
        queue.rear=-1;
        return queue;
    }

在不考虑队列为空的情况下,出队列头指针front++,在不考虑溢出的情况下,进队列尾指针rear++

    public static boolean inQueue(Queue queue,Object value){
        queue.data[++queue.rear]=value;
        return true;
    }
    public static Object outQueue(Queue queue){
        return queue.data[++queue.front];
    }

但是这样会遇到问题,如下图
这里写图片描述
当队尾指针指向了数组的最后一个位置,而队头指针不在0号位置时,他会出现假溢出的现象,即数组中有空位置,但是默认已经满了。为了解决这一问题,我们引入了循环队列,即将队尾和对头连接起来

循环队列

这里写图片描述
循环队列的数据结构还是和普通队列一样,只不过在设置空队列时将,rear和front设为了MAX_SIZE-1

class CycleQueue {
    Object[] data;
    int front;
    int rear;
}
public static CycleQueue initEmptyQueue(){
    CycleQueue cycleQueue=new CycleQueue();
    cycleQueue.data=new Object[MAX_SIZE];
    cycleQueue.front=MAX_SIZE-1;
    cycleQueue.rear=MAX_SIZE-1;
    return cycleQueue;
}

在进行判空的时候,只需要判断front和rear是否相等

public static boolean isEmpty(CycleQueue cycleQueue){
    if(cycleQueue.front==cycleQueue.rear)
        return true;
    return false;
}

接下来就是队列中最重要的两个函数,出队列和入队列。出队列的思想:当队列不为空的时候,将队列的第一个元素出出队列,用数学公式表达就是front=(front+1)%MAX_SIZE,然后返回该位置;进队列的思想是,先判断front指针和rear指针是否直接相邻,若是直接相邻,则表示队列已满,无法插入,若不相邻,则直接插入,插入的位置为:rear=(rear+1)%MAX_SIZE.

    public static boolean inQueue(CycleQueue cycleQueue,Object value){
        if((cycleQueue.rear+1)%MAX_SIZE==cycleQueue.front)
            return false;
        cycleQueue.rear=(cycleQueue.rear+1)%MAX_SIZE;
        cycleQueue.data[cycleQueue.rear]=value;
        return true;
    }

    public static Object outQueue(CycleQueue cycleQueue){
        if(isEmpty(cycleQueue)){
            return null;
        }   
        cycleQueue.front=(cycleQueue.front+1)%MAX_SIZE;
        return cycleQueue.data[cycleQueue.front];
    }

链队列

为甚么要使用练队列呢?其实和链栈的思想是一致的,因为顺序队列总是需要分配固定的内存空间,若分配过大,容易造成空间浪费,若是分配过小,容易造成溢出,所以我们才使用了链队列,在使用的过程中动态的分配空间。首先先看一下链队列的数据结构

//将头尾指针封装在一起
class LinkQueue{
    Node rear;
    Node front;
}
//链队列节点的类型
class Node{
    Node next;
    Object value;
}

首先创建一个带头结点的空队列

    public static LinkQueue initEmptyLinkQueue(){
        LinkQueue linkQueue=new LinkQueue();
        Node head=new Node();
        head.next=null;
        linkQueue.rear=linkQueue.front=head;
        return linkQueue;
    }

判断队列是否为空的思想和循环队列相同,即判断头尾指针是否相等

    public  static boolean isEmpty(LinkQueue linkQueue){
        if(linkQueue.rear==linkQueue.front)
            return true;
        return false;
    }

最后看进队列和出队列两个函数。进队列的思想是:利用单链表尾插法的思想插入到链表的尾部,具体可参考单链表的创建;出队列的思想是:如果队列不为空,则将对列的头指针指向第一个节点的下一个节点,然后返回第一个节点的值。

    public static boolean inQueue(LinkQueue linkQueue,Object value){
        Node node=new Node();
        node.value=value;
        node.next=linkQueue.rear.next;
        linkQueue.rear.next=node;
        linkQueue.rear=node;
        return true;
    }
    public static Object outQueue(LinkQueue linkQueue){
        if(isEmpty(linkQueue)){
            return null;
        }
        Node node=linkQueue.front.next;
        linkQueue.front.next=node.next;
        if(linkQueue.front.next==null)
            linkQueue.rear=linkQueue.front;
        return node.value;
    }

至此。队列的基本操作就完成了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值