数据结构--队列

Posted 浅灰色的记忆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构--队列相关的知识,希望对你有一定的参考价值。

什么是数据结构?
相互之间存在一种或多种特定关系的数据元素的集合。

1、什么是队列?
先进先出(FIFO:first in first out)

普通队列:队列有两种排发:1、、每处理一条数据,后面的数据都会依次前进一位。(效率较低)。2、、每处理一条数据,就会去下一条数据的空间处理下一位。(占用内存,浪费空间)

如果使用售票员和排队买票的说法,那么第一种是排队的人动,第二种是售票员动;


环形队列:有顺时针和逆时针之说,以第二种方法排队。(优点:提高效率的同时,可以充分使用内存,不会占用空间

创建队列:传入一个队列的容量初始化一个队列
销毁队列:销毁已存在的指定队列,因为创建队列是使用数组从创建的,所以必须要使用销毁数组的方式进行销毁,否则会造成内存泄漏
清空队列:将这指定队列中的元素清空,使该队列的长度为0(传入队尾、队首和队列长度三项置为0即可)
判空队列:判断指定队列是否是空队列(即判断队列长度是否为0,如果等于0则返回true,否则返回false)
判满队列:判断指定队列的队列长度和队列容量是否相同(相同则返回true,否则返回false)
队列长度:返回指定队列的元素个数据,统计队列的长度
新元素入队:自动加入到指定队列的最后一位(如果队列是满的,返回false,如果队列是空的,则加入队列的最后一位,队尾做自增操作并 取余队列容量,指向下一个位置,并使队列的长度加一
首元素出队:删除该队列的第一个元素(如果当前队列是空的,返回false,如果不为空,则获取当前队列的队头,进行删除,队头做自增操作并 取余队列容量,指向下一个位置,并使队列的长度减一

注:此处做取余操作,是因为需要考虑队尾值如果超过了容量的情况, 被取余数 < 取余数  结果 等于自己本身,避免数组越界。


遍历队列:输出该队列的所有元素(使用 for 循环,以队首的下标为起始,以队列的长度+队首的下标(此处是因为队首的数字增加了,那么队首到长度之间的循环次数就会缩减,所以长度需要加上队首的下标)为终结,对 i 进行自增,并对 i 取余容量(此处注意:是对队列的容量进行取余,不要对队列的长度进行取余)同样进行取余操作)
新元素入队和首元素出队操作,因为是环形队列,所以当环形队列走了一圈之后队或队伍再进行自增就会下标越界,导致程序错误,所以需要取余于队列容量

下方附上队列数据结构代码:

package util;

public class MyQueue {
    //队列数组指针
    private Object[] myQueue;
    //队列长度
    private int myQueueLen;
    //队列容量
    private int myQueueCapacity;
    //队列头的指针
    private int myQueueHead;
    //队列尾的指针
    private int myQueueTail;
    
    public MyQueue() {
        super();
    }

    /**
     * 初始化队列内存空间
     * @param queueCapacity 队列容量
     * @return 
     */
    public MyQueue(int queueCapacity){
        myQueueCapacity = queueCapacity;

        // 申请内存空间
        myQueue = new Object[myQueueCapacity];
        clearQueue();
    }
    
    /**
     * 将数组赋值为null,垃圾回收器会自动回收
     */
    public void deleteQueue(){
        myQueue = null;
    }
    
    /**
     * 清空队列
     */
    public void clearQueue(){
        myQueueHead = 0;
        myQueueTail = 0;
        myQueueLen = 0;
    }
    
    /**
     * 使用三目运算符,判断队列的长度是否等于0
     * @return boolean 相等返回true,不相等返回false
     */
    public boolean isNullQueue(){
        return 0 == myQueueLen ? true : false;
    }
    
    /**
     * 使用三目运算符,判断队列的长度是否等于队列的容量
     * @return boolean 相等返回true,不相等返回false
     */
    public boolean isFullQueue(){
        return myQueueLen == myQueueCapacity ? true : false;
    }
    
    /**
     * 直接根据数组的length方法返回队列的长度
     * @return
     */
    public int queueLen(){
        return myQueueLen;
    }
    
    /**
     * 判断队列是否已经满队,添加元素到队列中,并更新队头和长度的下标
     * @param element
     * @return
     */
    public boolean addElement(Object element){
        if(isFullQueue())
        {
            return false;
        } 
        else
        {
            myQueue[myQueueTail] = element;
            ++ myQueueTail;
            myQueueTail = myQueueTail % myQueueCapacity;
            myQueueLen ++;
            return true;
        }
    }
    
    /**
     * 判断队列是否是空队,删除队列中的第一个元素,并更新队头和长度的下标
     * @return
     * @throws Exception 
     */
    public Object delElement() throws Exception{
        if (isNullQueue()){
            throw new Exception("队列为空,不能删除元素");
        } 
        else 
        {
            Object element = myQueue[myQueueHead];
            myQueueHead = ++ myQueueHead % myQueueCapacity;
            myQueueLen --;
            return element;
        }
    }
    
    public void queueTraverse(){
        for (int i = myQueueHead; i < myQueueLen + myQueueHead; i++)
        {
            Object element = myQueue[i % myQueueCapacity];
            
            System.out.println(element.toString()+"");
        }
    }
}

  测试数据结构效果:

package use.test;

import test.entity.Person;
import util.*;

public class TestMyQueue {
    public static void main(String[] args) {
        MyQueue myQueue = new MyQueue(4);
        
        Person person1 = new Person();
        person1.setAddress("合肥市蜀山区");
        person1.setName("张三");
        person1.setAge(22);
        
        Person person2 = new Person();
        person2.setAddress("南京市江宁区");
        person2.setName("李四");
        person2.setAge(44);
        
        Person person3 = new Person();
        person3.setAddress("合肥市庐阳区");
        person3.setName("王五");
        person3.setAge(35);
        
        //添加队列
        myQueue.addElement(person1);
        myQueue.addElement(person2);
        myQueue.addElement("wangwu");
        myQueue.addElement(person3);
        
        System.out.println("队列的长度:"+myQueue.queueLen());
        myQueue.queueTraverse();
        
        //删除队列
        try {
            //删除时,如果队列为空,则会跑出Exception异常
            Object element1 = myQueue.delElement();
            System.out.println("当前删除的元素为" + element1.toString());
            Object element2 = myQueue.delElement();
            System.out.println("当前删除的元素为" + element2.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        
        System.out.println("队列的长度:"+myQueue.queueLen());
        myQueue.queueTraverse();
        
        //添加队列
        myQueue.addElement(5);
        myQueue.addElement(6);
        myQueue.addElement(7);
        
        System.out.println("队列的长度:" + myQueue.queueLen());
        myQueue.queueTraverse();
        
        //清空队列
//        myQueue.clearQueue();
        if (myQueue.isNullQueue())
        {
            System.out.println("队列为空");
        }
        
        if (myQueue.isFullQueue())
        {
            System.out.println("队列为满");
        }
        System.out.println("队列的长度:" + myQueue.queueLen());
        
    }
}

  

以上是关于数据结构--队列的主要内容,如果未能解决你的问题,请参考以下文章

perl中的队列

IPC System V 消息队列 - 发送一个数组块

JDK常用数据结构

完全下载文件时,将下载的文件从一个片段传递到另一个片段

RocketMQ - 如何用死信队列解决消费者异常

rabbitmq - 不会获取队列中的所有消息