精华内容
下载资源
问答
  • 没错,队列也是一种线性表(顺序表),所以队列的顺序存储结构可能在学过栈之后就显得很简单了,相同的思路,但是要注意的是队列是先进先出(也就是早期的鸟儿有虫吃,早来的鸟儿早虫) 队列 先来看一看队列的概念...

    说到队列,我们先来回顾一下之前所讲的栈,栈是一种先进后出的线性表,而队列与栈是相反的一种线性结构,对!没错,队列也是一种线性表(顺序表),所以队列的顺序存储结构可能在学过栈之后就显得很简单了,相同的思路,但是要注意的是队列是先进先出(也就是早期的鸟儿有虫吃,早来的鸟儿早虫)

    队列

    先来看一看队列的概念:队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。SO?刚刚我没有说错吧,队列也是一种线性表。

    • 队列的接口Queue:

    public interface Queue <E>{
       public int getSize();
       public boolean isEmpty();
       public void clear();
       
       /**
        * 入队一个新元素e
        * @param e
        */
       public void enqueue(E e) ;
       /**
        * 出队一个元素e
        * @return
        */
       public E dequeue();
       /**
        * 获取队头元素
        * @return
        */
       public E getFront();
       /**
        * 获取队尾元素
        * @return
        */
       public E getRear();
    }

    关于队列的实现,同样是实现队列的接口Queue,并且实现其接口里面的方法

    public class ArrayQueue<E> implements Queue<E> {
    
    
    
    }

    接下来我们来看一看入队和出队的具体操作,因为队列是一种线性表,所以它所要实现的方法可以完全调用线性表的方法入

    • 入队:入队元素的时候我们的rear指针要往后移动

    • 出队:出队的时候我们的rear指针往前移,和入队相反

       private ArrayList<E> list; //实现线性顺序存储结构ArrayList
    
    	public ArrayQueue() {        //无参的构造函数,创建一个默认大小的线性表
    		list = new ArrayList<E>();
    	}
    
    	public ArrayQueue(int capacity) {   //有参的构造函数,创建一个指定容量的队列(线性表)
    		list = new ArrayList<E>(capacity);
    	}
    
    	@Override
    	public int getSize() {    //获得有效长度
    		// TODO Auto-generated method stub
    		return list.getSize();
    	}
    
    	@Override
    	public boolean isEmpty() {    //判断队列是否为空
    		// TODO Auto-generated method stub
    		return list.isEmpty();
    	}
    
    	@Override
    	public void clear() {   //清空对列
    		// TODO Auto-generated method stub
    		list.clear();
    	}
    
    	@Override  
    	public void enqueue(E e) {   //入队列一个新元素,相当于线性表在末尾插入一个新的元素
    		// TODO Auto-generated method stub
    		list.addLast(e);
    	}
    
    	@Override
    	public E dequeue() {      //出队列,队列先入先出,所以相当于线性表中删除第一个元素
    		// TODO Auto-generated method stub
    		return list.removeFirst();
    	}
    
    	@Override
    	public E getFront() {   //获取队头
    		// TODO Auto-generated method stub
    		return list.getFirst();
    	}
    
    	@Override
    	public E getRear() {   //获取队尾
    		// TODO Auto-generated method stub
    		return list.getLast();
    	}
    
    	@Override
    	public String toString() {  //toString()方法的重写
    		StringBuilder sb = new StringBuilder();
    		sb.append("ArrayQueue: size=" + getSize() + ",capacity=" + list.getCapacity() + "\n");
    		if (isEmpty()) {
    			sb.append("[]");
    		} else {
    			sb.append('[');
    			for (int i = 0; i < getSize(); i++) {
    				sb.append(list.get(i));
    				if (i == getSize() - 1) {
    					sb.append(']');
    				} else {
    					sb.append(',');
    				}
    			}
    		}
    		return sb.toString();
    	}
    
    	@Override
    	public boolean equals(Object obj) {  //equals()方法比较的是两个队列的内容
    		if (obj == null) {
    			return false;
    		}
    		if (obj == this) {
    			return true;
    		}
    		if (obj instanceof ArrayQueue) {
    			ArrayQueue queue = (ArrayQueue) obj;
    			return list.equals(queue.list);  //因为实现的是线性表,所以直接调用list方法
    		}
    		return false;
    	}

          我们的队列存储结构本身是由ArrayList实现的,入队相当于线性表表尾添加元素,出队相当于线性表表头删除元素,所以入队的时间复杂度是O(1),而出队则是O(n),那么能否进行优化,使得出队和入队的时间都是O(1)呢?好,那么接下来就引入了循环队列的概念。

    循环队列

    今天的重点来了,请睁大你的双眼,动起你的小脑瓜,认真学习,因为循环队列很重要!很重要!很重要!(重要的事情说三遍)

    接着我们上面的这个问题,怎样进行优化呢?我们分为三步:

    第一步:因为之前的队列我们只有一个rear指针,那么我们能否引进两个指针,使得一个指向尾一个指向头,所以我们就有了front指针指向队列的头结点,rear指针指向队列的尾结点,从而在移动元素的时候(入队元素和出队)头指针和尾指针也随之移动。

    这样的话我们是解决了出队和入队的时间复杂度都是O(1)的问题,但是当rear指针移动到队列尾端的时候现在是不能插入元素了,rear指针也不能再移动了,同时也浪费了很多空间,于是乎我们又有了新的解决方案

    第二步:当我们遇到第一步所遇到的问题时,不管是头指针还是尾指针当他们达到队列最后端的时候不能再移动的时候,我们将他们重新移动到对头。

         也就相当于头和尾连接起来了,相当于一个环形

    那么在这种情况下我们如何判断这个队列什么时候已经满了,什么时候队列为空呢?

    队列已满:(rear+1)% n==front
    出队列还剩一个元素
    队列为空 (rear+1)%n==front

    这样设计的我们完美的解决了上一步所说的空间浪费的问题,但是判空和判满的条件都是 (rear+1)%n==front???纳尼??????这要怎么办,别着急,这不?优化第三步

    第三步:预留出来一个空空间,不存放任何元素,尾指针rear始终指向这个空空间,当插入元素的时候,rear指针始终往后移,指向一个null

          那么现在你肯定想要问,怎么判断队列为空?又怎样判断队列满了呢?别着急,接着往下看

    队列已满  (rear+1)%n==front

     

    队列只剩一个元素
    队列为空  rear==front

          完美!!!!这样就解决了第二步中的判断满和判断空条件一致的问题,这个时候你肯定要说那这样尾指针一直指向一个空空间,不就造成了空间浪费吗?那么我就想反问你一句咯,这一个空间和第一步那么多空间相比,是不是小到可以忽略不记,简直就是小巫见大巫,不值得一提

        那么接下来就来看看代码部分的实现吧!

    public class ArrayQueueLoop<E> implements Queue<E>{
    
    
    }
    • 成员变量:我们需要有的成员变量有指向对头的头指针,指向队尾的尾指针,另外还需要创建一个新的数组,以及一个能够表示有效长度的变量,同时还需要一个静态常量用来表示默认队列大小
        private E[] data;
        private int front;
        private int rear;
        private int size;
        private static int DEFAULT_SIZE=10;
    • 构造函数(有参无参):分为为指定大小的队列和默认大小的队列
        public ArrayQueueLoop() {
        	this(DEFAULT_SIZE);
        }
        public ArrayQueueLoop (int capacity) {
        	data=(E[]) new Object[capacity+1];
        	front=0;
        	rear=0;
        	size=0;
        }
    • getSize():获取有效长度,只要返回size即可
        @Override
    	public int getSize() {
    		// TODO Auto-generated method stub
    		return size;
    	}
    
    • isEmpty():判断队列是否为空,只要满足头指针等于尾指针以及有效长度为零即可
        @Override
    	public boolean isEmpty() {
    		// TODO Auto-generated method stub
    		return front==rear&&size==0;
    	}
    • clear() :清空队列也就是让头指针和尾指针均指向null,有效长度size等于0
        @Override
    	public void clear() {
    		// TODO Auto-generated method stub
    		front=0;
        	rear=0;
        	size=0;
    	}
    • enqueue(E e):入队元素,入队一个元素,尾指针后移就可以了,但是要注意的是扩容的问题,当队列已满的时候,我们需要扩容的操作
         @Override
    	public void enqueue(E e) {
    		// TODO Auto-generated method stub
    		if((rear+1)%data.length==front) {
    			//扩容
    			resize(data.length*2-1);
    		}
    		data[rear]=e;
    		rear=(rear+1)%data.length;
    		size++;
    		
    	}
    • dequeue():出队操作是出队元素的时候头指针后移即可,但是出队同样要考虑容量的问题,必要的时候需要缩容,缩容的条件是当有效长度小于队列长度的四分之一的时候,同时还有满足此时队列的长度要大于默认的队列长度,才可以进行缩容的操作
         @Override
    	public E dequeue() {
    		// TODO Auto-generated method stub
    		if(isEmpty()) {
    			throw new NullPointerException("队列为空");
    		}
    		E e=data[front];
    		front=(front+1)%data.length;
    		size--;
    		if(size<=data.length/4&&data.length>DEFAULT_SIZE) {
    			//缩容
    			resize(data.length/2+1);
    		}
    		return e;
    	}
    • resize():改变容量大小的一个方法,缩容和扩容都需要调用这个方法
    第一种 扩容的情况
    第二种 扩容的情况

          第一种扩容的情况就是建立一个新的队列,长度是原来的二倍,直接把原来的队列放到新的队列中,第二种则是需要从头开始遍历直至尾指针所在的位置,然后将遍历结果放到新数组中,头指针和尾指针做出相应的更新。

         缩容和扩容的情况一致,这里就不做过多的介绍了,如果看到文章的你有问题的话,可以评论区call我

      private void resize(int newLen) {
    		// TODO Auto-generated method stub
    		E[] newData=(E[]) new Object[newLen];
    		int index=0;//表示新数组的角标
    		for(int i=front;i!=rear;i=(i+1)%data.length) {
    			newData[index++]=data[i];
    		}
    		front=0;
    		rear=index;
    		data=newData;
    	}
    •  getFront():获得对头元素
        @Override
    	public E getFront() {
    		// TODO Auto-generated method stub
    		return data[front];
    	}
    • getRear():获取队尾元素(要注意是循环队列)
         @Override
    	public E getRear() {
    		// TODO Auto-generated method stub
    		return data[(data.length+rear-1)%data.length];
    	}
    • toString():toString()方法的重写,拼接字符串
             @Override
    	  public String toString() {
    		// TODO Auto-generated method stub
    		StringBuilder sb=new StringBuilder();
    		sb.append("ArrayQueueLoop:size="+getSize()+",capacity="+(data.length-1)+"\n");
    		if(isEmpty()) {
    			sb.append("[]");
    		}else {
    			sb.append('[');
    			for(int i=front;i!=rear;i=(i+1)%data.length) {
    				sb.append(data[i]);
    				if((i+1)%data.length==rear) {
    					sb.append(']');
    				}else {
    					sb.append(',');
    				}
    			}
    		}
    		return sb.toString();
    		
    	  }
    • 测试类:
       public static void main(String[] args) {
    		// TODO Auto-generated method stub
            ArrayQueueLoop<Integer> queue=new ArrayQueueLoop<Integer> ();
    	   /* for(int i=1;i<=10;i++) {
    	    	queue.enqueue(i);
    	    }
    	    System.out.println(queue);*/
    	    for(int i=1;i<=15;i++) {
    	    	queue.enqueue(i);
    	    }
    	    System.out.println(queue);
    	    for(int i=1;i<=10;i++) {
    	    	queue.dequeue();
    	    }
    	    System.out.println(queue);
    	    
    	    
    	  
    	}

    运行结果:

      好啦,队列的顺序结够总结完啦,不知不觉都这么晚了。。。。。

    展开全文
  • 1 定义  队列是只允许在...2 队列的顺序存储结构 (1)队列顺序存储的不足--引出循环队列  假设个队列有n个元素,则顺序存储的队列需要建立个大于n的数组,并把队列的所有元素存储在数组的前n个单元,数...

    1 定义
      队列是只允许在一端进行插入操作,另一端进行删除操作的线性表。
      队列是一种先进先出(FIST IN FIRST OUT)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为对头。

    2 队列的顺序存储结构
    (1)队列顺序存储的不足--引出循环队列

        假设一个队列有n个元素,则顺序存储的队列需要建立一个大于n的数组,并把队列的所有元素存储在数组的前n个单元,数组下标为0的一端即为对头。
        所谓的入队,就是在队尾追加一个元素,不需要移动任何元素,所以时间复杂度为O(1).
        队列的出队是在对头,即下标为0的位置,也就意味着,队列中的所有位置都得向前移动,以保证下标为0的位置,即对头不为空。此时时间复杂度为O(n)。

        可是有时候想想,为什么出队列时一定要全部移动呢?如果不限制队列的元素一定要存储在数组的前n个单元,出队的性能就会大大增加。也就是说,队头不需要一定在下标为0的位置。

        为了避免当只有一个元素时,对头和队尾重合使得处理变得麻烦,所以引入两个指针,front指针指向对头元素,rear指针指向队尾元素的下一个元素。这样当front等于rear时,不是队列中有一个元素,而是表示空队列。

        假设数组的长度为5,空队列及初始状态如左图所示,front与rear指针都指向下标为0的位置。当队列中有4个元素时,front指针不变,rear指针指向下标为4的位置。

        此时出队两个元素,则front指针指向下标为2的位置,rear不变。再入队一个元素,front指针不变,此时rear指针移动到数组之外。

        假设这个队列中的总个数不超过5个,但目前如果接着入队的话,会导致数组越界的错误,但是队列在下标为0和1的位置是没有元素的。我们把这种现象叫做“假溢出”。

        为了解决“假溢出”的问题,我们引入循环队列。

    (2)循环队列

      为了解决“假溢出”的办法,就是队后面满了,再从头开始,也就是头尾相接的循环。我们把队列的这种投喂相接的顺序存储结构称为循环队列。

      继续刚才的例子,将rear指针指向下标为0的位置,就不会导致rear指针指向不明的问题。

      接着入队两个元素,会发现rear指针与front重合了。

      此时问题又来了,刚才说了,当rear等于front时,表示是空队列,现在当队列满时,rear也等于front。那么如何判断队列到底是空的还是满的了?

      解决办法为:当队列空时,判断条件就是rear=front, 当队列满时,我们修改其判断条件,保留一个元素空闲。也就是说,队列满时,数组中还有一个空闲单元。以下两种情况,我们都认为队列已经满了。

      由于rear可能比front大,也可能比front小,所以假设队列的最大尺寸为QueueSize, 队列满的判断条件改为(rear + 1)%QueueSize = front. 队列的长度为(rear - front + QueueSize)% QueueSize.

     

    循环队列的顺序存储结构为

    typedef int QElemType;
    typedef struct {
        QElemType data[MAXSIZE];
        int rear;            //头指针
        int front;           //尾指针,若队列不为空,指向队尾元素的下一个元素
    }SqQueue;

    循环队列的初始化

    //初始化一个空队列
    Status InitQueue(SqQueue *Q) {
        Q->rear = 0;
        Q->front = 0;
        return OK;
    }

    循环队列求当前队列的长度

    //返回Q的元素个数,也就是队列的当前长度
    int QueueLength(SqQueue Q) {
        return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
    }

    循环队列的入队操作

    //若队列未满,插入元素e为新的队尾元素
    Status insertQueue(SqQueue *Q, QElemType e) {
        if ((Q->rear + 1) % MAXSIZE == Q->front) {    //队满
            return ERROR;
        }
        Q->data[Q->rear] = e;
        Q->rear = (Q->rear + 1) % MAXSIZE;
        return OK;
    }

    循环队列的出队操作

    //若队列不为空,删除Q的对头元素,并用e返回
    Status deleteQueue(SqQueue *Q, QElemType *e) {
        if (Q->rear == Q->front) {                //队空
            return ERROR;
        }
        *e = Q->data[Q->front];
        Q->front = (Q->front + 1) % MAXSIZE
        return OK;
    }

     

    转载于:https://www.cnblogs.com/muzijie/p/5650187.html

    展开全文
  • 队列线性表的一种特殊形式,它只允许在线性表的一端进行插入,而在另一端进行删除,也就是所谓的先入先出 用顺序存储结构实现队列,假如队列有n个元素,则必须建立大于n的数组,因为队列要求在一端插入,而在...

    队列也是线性表的一种特殊形式,它只允许在线性表的一端进行插入,而在另一端进行删除,也就是所谓的先入先出

    用顺序存储的结构实现队列,假如队列有n个元素,则必须建立大于n的数组,因为队列要求在一端插入,而在另一端删除,所以插入元素时,时间复杂度为O(1),而在删除的时候,所有元素都得向前移动一个位置,时间复杂度为O(n),为了更好的利用空间,所以提出了循环结构:

    将原本的顺序存储结构进行首尾相接得到的队列就是循环队列

    循环对列的存储结构{

    data[]:用来存储数据的数组

    front:头指针,指向队列的第一个元素

    rear:尾指针:指向队列的下一个空位置

    }

    循环队列的代码实现:

    package seqList;
    /*
     * 顺序循环链表
     * 队头(front),队尾(rear)
     * 队空:front==rear
     * 队满:(rear+1)%queueSize==front
     * 队列的当前长度:(rear-front+queueSize)%queueSize
     */
    
    public class SqQueue {
    	private int DefaultSize=100;
    	private int size;
    	private Object[] Queue;
    	private int front;
    	private int rear;
    	
    	public SqQueue() {
    		this.size=DefaultSize;
    		initQueue(DefaultSize);
    	}
    	//有参构造函数
    	public SqQueue(int size) {
    		this.size=size;
    		Queue=new Object[size];
    		front=0;
    		rear=0;
    	}
    	//无参构造函数
    	public void initQueue(int size) {
    		Queue=new Object[size];
    		front=0;
    		rear=0;
    	}
    	
    	//入队列
    	public void EnQueue(Object data) throws Exception {
    		
    		if((rear+1)%size==front) {
    			throw new Exception("队列已满");
    		}
    		else {
    			Queue[rear]=data;
    			rear=(rear+1)%size;
    		}
    	}
    	//出队列
    	public Object deQueue() throws Exception {
    		if(rear==front) {
    			throw new Exception("队列为空");
    		}
    		else {
    			Object x=Queue[front];
    			front=(front+1)%size;
    			return x;
    		}
    	}
    	//获得队列的长度
    	public int queueLength() {
    		return (rear-front+size)%size;
    	}
    	public static void main(String[] args) throws Exception {
    		SqQueue sq=new SqQueue(5);
    		sq.EnQueue(1);
    		sq.EnQueue(2);
    		sq.EnQueue(3);
    		System.out.println(sq.queueLength());
    	    System.out.println(sq.deQueue());
    	    System.out.println(sq.deQueue());
    	    System.out.println(sq.deQueue());
    	}
    
    }

    运行结果:

    展开全文
  • 队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。如图所示: 二、循环队列的引出 为了避免当队中只剩一个元素的时候,队头队尾重合使处理变得麻烦。...

    一、队列的定义
    队列( queue )是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
    队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。如图所示:
    在这里插入图片描述
    二、循环队列的引出
    为了避免当队中只剩一个元素的时候,队头队尾重合使处理变得麻烦。所以我们引入两个指针,front指针指向队头元素,rear指针指向队尾元素。这样当front=rear时,队列中不是只剩一个元素,而是它是一个空队列。而且这样也大大方便了我们删除队头元素。这样就当我们删除队头元素时就只需要移动front指针,这样可以大大降低算法的时间复杂度。
    但是当删除元素的时候,front不断后移,前面的位置不断空出来。插入元素时rear指针 b不断后移。对于一个有限的队列来说,在不断得插入元素时rear最终会指向一个无效位置。具体情况如下图所示:
    删除元素时:
    在这里插入图片描述
    插入元素时:
    在这里插入图片描述
    用循环队列可以巧妙得解决这个问题。
    三、循环队列
    1、循环队列的定义
    **我们把队列的这种头尾相接的顺序存储结构称为循环队列。**如下图所示:
    循环队列满时:
    在这里插入图片描述
    循环队列空时:
    在这里插入图片描述
    判断循环队列空的条件是:

    front == rear;

    判断循环队列满的条件是:

    (rear+1)%6==front

    为了区别判空和判满的状态,我们总在插入元素时牺牲一个空间来区别这两种状态,这也是为啥判满的时候是(rear+1)%6==front
    2、循环队列的简单实现
    (1)循环队列的整体结构的设计

    typedef int ElemType;
    #define MAX_SIZE 10
    typedef structc Queue
    {
    	ElemType arr[MAX_SIZE];
    	int front;//队头指针
    	int rear;//队尾指针
    };Queue,pQueue
    

    2、初始化(init)
    初始化的时候我们只需要将我们的头指针和尾指针置成0即可。

    void init(pQueue pqu)
    {
    	if(pqu != NULL)
    	{
    	pqu->front = pqu->rear = 0;
    	}
    } 
    

    3、入队操作(enqueue)
    在进行入队操作之前我们首先应该对队列进行判满的操作。如果队列是满的,我们就插入不了元素。如果队列不满我们就可以进行我们的入队操作。
    判满

    int full(pQueue pqu)
    {
    	return (pqu->rear + 1)%MAX_SIZE == front ? 1 : 0;
    }
    

    插入元素
    插入元素时,我们只需要将这个队列中的rear指针的下标置成我们要插入的元素即可。

    int enqueue(pQueue pqu,ElemType val)
    {
    	if(full(pqu))
    	{
    	return 0;
    	}
    	pqu->arr[pqu->rear] = val;
    	pqu->rear = (pqu->rear + 1)%MAX_SIZE;
    	return 1;
    }
    

    4、出队操作(dequeue)
    在进行出队操作时,我们首先要判断的是队列是否为空。若队列中的元素为空,则就无法进行出队的操作。
    判空

    int empty(pQueue pqu)
    {
    	return (pqu->rear == pqu->front) ? 1 : 0;
    }
    

    出队操作

    int dequeue(Pqueue pqu)//只是删除元素
    {
    	if(empty(pqu))
    	{
    	return 0;
    	}
    	pqu->front = (pqu->front + 1) % MAX_SIZE;
    	return 1;
    }
    

    5、获取队头元素(front)

    int front(pQueue pqu)
    {
    	if(empty(pqu))
    	{
    	return -1;//牺牲一个数值位
    	}
    	return pqu->arr[pqu->front];
    }
    

    6、获取队尾元素(back)

    int back(pQueue pqu)
    {
    	if(empty(pqu))
    	{
    	return -1;//队列为NULL
    	}
    	return pqu->arr[(pqu->rear + MAX_SIZE - 1)%MAX_SIZE];
    }
    
    展开全文
  • 队列是一种先进先出(First In Last Out)的线性表,简称FIFO 允许插入的一端称为队尾,允许删除的一端称为队头 队列接口Queue的定义 队列的具体实现 package DS01.动态数组; public interface Queue<E> ...
  • 我们在《栈的顺序存储结构》中发现,栈操作的top指针在Push时增大而在Pop时减小,栈空间可以重复利用的,而队列的front、rear指针都在一直增大,虽然前面的元素已经出队了,但它所占的存储空间却不能重复利用。...
  • 顺序存储的队列写起来跟顺序实现的栈很像,也采用数组存储数据,但是在不断入队列和出队列过程中,数据会不断后移,所以会造成大量的空间浪费,所以这里我们采用循环队列的形式 循环队列长度 我们需要知道,循环...
  • 循环队列的顺序存储

    2019-05-06 21:53:46
    队列是一种操作受限(先进先出)的线性表,今天我们来实现队列的顺序存储结构。 在队列的顺序存储中,用一组地址连续的存储单元依次存放队头到对尾的数据元素,即为顺序队列。 定义一个静态数组,每次尾插元素,即...
  • 队列是一种先进先出(First In First out)线性表,允许插入一端称为队尾,允许删除一端称为队头。 3. 队列顺序存储有什么不足? 使用数组实现的顺序存储,当做出队列操作时,所有元素都需要向前移动一...
  • 队列是一种先进先出的线性表,只允许在一端进行插入操作,另一端进行删除操作。队列顺序存储的基础操作和线性表顺序存储的基础操作几乎相同,但因为队列的增加和删除操作都需要让整个数组的数据进行移动,性能上并不...
  • 我们在《栈的顺序存储结构》中发现,栈操作的top指针在Push时增大而在Pop时减小,栈空间可以重复利用的,而队列的front、rear指针都在一直增大,虽然前面的元素已经出队了,但它所占的存储空间却不能重复利用。...
  • 队列的一种顺序存储称为顺序队列。 与顺序栈类似,在队列的顺序存储结构中,用一组地址连续的存储单元依次存放从队头到队尾的元素,如一维数组 Queue[MAXSIZE]。 由于队列中队头和队尾的位置都动态变化的,因此...
  • 一、队列:队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列是一种先进先出(First In First Out)的线性表,简称... 三、队列顺序存储的不足:把队列的所有元素存储在数组的前n个单元,数...
  • 队列的顺序存储结构

    2019-10-05 01:56:45
    队列的顺序存储结构循环队列 队列的定义:只允许在一端进行操作,在另一端进行删除操作的线性表。 队列是一种先进先出的线性表,简称FIFO,允许插入的一端称为队尾,允许删除的一端称为队头。 1、队列的顺序...
  •   队列(Queue) 简称队,也是一种操作受限线性表,只允许在表一端进行插入,而在表另一端进行删除。向队列中插入元素称为入队或进队。删除元素称为出队或离队。这和我们日常生活中排队一致,最早排队...
  • 队列(queue)是只允许在一端进行插入操作,而在另一端...循环队列是一种头尾相接的顺序存储结构。 具体实现代码如下: /* SqQueue.h 头文件 */ /*循环队列,保留一个元素空间为空,用来区分队列是满还是空*/ #inc...
  • 目录队列结构的定义和属性队列结构的抽象数据类型顺序队列循环队列链队列 队列结构的定义和属性 定义:队列是一种与线性表相似的线性结构。...从队列的基本定义和操作来看,队列是一种具有先进先出特点的数据结构
  •  队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其另一端进行删除操作。...
  • 二、队列的顺序存储结构 1.顺序队列的定义 2.循环队列定义 3.循环队列的基本操作 三、队列的链式存储结构 1.链队列的定义 2.链队列的基本操作 前言 队列也是一种线性表,其特殊性在于队列的基本操作...
  • 队列的结构用链式存储方式最合适的,这不仅仅结构上的优势,更重要在于顺序存储结构会造成“假溢出”现象。 假溢出现象数队头由于出队操作,还有剩余空间,但队尾指针已达到数组的尾部,继续插入元素,队尾指针...
  • 队列是一种特殊的线性表,它的特殊性体现在,它只能够从一段进,从另一端出,遵循先入先出的原则。这种独特的规则,可以运用在程序设计中的很多...//描述:队列的顺序存储结构,该队列为循环队列队列的创建,插入,
  • 组地址连续的存储单元依次存储从队头到队尾数据元素就是顺序队列,和顺序的存储差不多,两数据结构区别就在于顺序队列(循环队列也如此)空间占满时不再额外给元素分配空间,顺序表会顺延额外分配个,...
  • 顺序循环队列

    2019-09-26 23:33:34
    一 顺序表循环队列 1.1 顺序循环队列定义 队列是一种运算受限的先进先出线性表,仅允许在... 队列的顺序存储结构使用一个数组和两个整型变量实现,其结构如下: 1 struct Queue{ 2 ElemType elem[MaxSize]; ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 419
精华内容 167
关键字:

循环队列是队列的一种顺序存储结构