精华内容
下载资源
问答
  • 代码有详解 易懂 功能实现较全 代码有详解 易懂 功能实现较全 代码有详解 易懂 功能实现较全
  • 循环队列(数组实现)

    2020-11-01 22:25:52
    循环队列(数组实现) 文章目录前言官方解析原题+代码解决了我心中的的疑惑小结 前言 今天,我又下定决心准备在来到LeetCode来看看算法。我对算法的无知让我对算法有了更加多的学习欲望,虽然自己没有什么天赋,但是...

    循环队列(数组实现)

    前言

    今天,我又下定决心准备在来到LeetCode来看看算法。我对算法的无知让我对算法有了更加多的学习欲望,虽然自己没有什么天赋,但是作为一个向上的程序员,这道坎还是要过的。队列算的上是最基本的数据结构了,但是今天的队列数据结构的构成却难倒了我,让我意识到了自己是有多菜,于是翻开官网回答,让我也是受益匪浅。下面就来讲讲我在写队列这个数据接结构的时候遇到的困难。

    • 首先,在写队列的时候我不清楚队列需要哪些属性
    • 第二,对于进队和出队的一些特殊情况我也不是很清楚
    • 第三,甚至初始化一个队列的时候我居然也不知道要干嘛
    • 第四,我又觉得自己好菜,但是,我还是站起来了!!!

    官方解析

    原题+代码

    返回目录

    设计循环队列

    class MyCircularQueue {
    
      private int[] queue;
      private int headIndex;
      private int count;
      private int capacity;
    
      /** Initialize your data structure here. Set the size of the queue to be k. */
      public MyCircularQueue(int k) {
        this.capacity = k;
        this.queue = new int[k];
        this.headIndex = 0;
        this.count = 0;
      }
    
      /** Insert an element into the circular queue. Return true if the operation is successful. */
      public boolean enQueue(int value) {
        if (this.count == this.capacity)
          return false;
        this.queue[(this.headIndex + this.count) % this.capacity] = value;
        this.count += 1;
        return true;
      }
    
      /** Delete an element from the circular queue. Return true if the operation is successful. */
      public boolean deQueue() {
        if (this.count == 0)
          return false;
        this.headIndex = (this.headIndex + 1) % this.capacity;
        this.count -= 1;
        return true;
      }
    
      /** Get the front item from the queue. */
      public int Front() {
        if (this.count == 0)
          return -1;
        return this.queue[this.headIndex];
      }
    
      /** Get the last item from the queue. */
      public int Rear() {
        if (this.count == 0)
          return -1;
        int tailIndex = (this.headIndex + this.count - 1) % this.capacity;
        return this.queue[tailIndex];
      }
    
      /** Checks whether the circular queue is empty or not. */
      public boolean isEmpty() {
        return (this.count == 0);
      }
    
      /** Checks whether the circular queue is full or not. */
      public boolean isFull() {
        return (this.count == this.capacity);
      }
    }
    

    解决了我心中的的疑惑

    返回目录

    1. 解决了写队列需要哪些属性的问题

    属性定义的原则:官方给出的解释是数据结构的关键是数据结构的属性设置,好的设计属性更加少,下面给出了几点原因

    • 属性少说明属性之间的冗余性更加少
    • 属性的冗余度越低,操作逻辑更加简单,发生错误的可能性就越低
    • 属性数量越少,空间复杂度就越低,性能就更好

    注意:属性也不是越少越好,在某些情况下,冗余的属性可以降低时间复杂度,达到时间和空间复杂度的平衡。相信写过业务代码的小伙伴都知道,数据表的设计上就经常会冗余一些字段减低某些业务的复杂度。

    最终队列需要定义的属性也就出来了,这里没有额外用到尾结点的属性,因为我们可以通过 headIndex 和 count 推断出尾结点的下标(tailIndex = (headIndex + count - 1)%capacity)

    • queue:一个固定大小的数组,也就是存放数据的容器
    • headIndex:队列的头结点下标
    • count:循环队列的当前长度
    • capacity:队列的最大容量

    2. 队列进队和出队我们需要考虑的特殊情况

    在做许多算法的时候我都会遇到这种问题,因为算法中都会有着特殊的节点需要进行特殊的处理,比如旋转字符串就需要在字符串达到中间值的时候进行结束。队列的进队和出队也是有着特殊情况,如下:

    • 进队:队列满的时候就是需要进行特殊处理的,尾结点移动到数组最大下标需要特殊处理
    • 出队:队列空的时候就是需要进行特殊处理的,头结点移动到数组最大下标需要特殊处理

    3. 队列的初始化需要做的事

    其实,你只要确定好了了你这个队列数据结构所需要的属性就可以知道初始化所需要做的事了。

    小结

    返回目录

    这个是数据结构的学习,也是比较基础的,下面就给出数据结构设计的要点

    • 属性的设计选择(思路还是要从这个结构能够完成的功能来说)
    • 特殊情况的处理,这个通常一下子是想不全面的,需要多测、多想

    心得

    个人有个毛病,就是总是想着第一次写代码就把这个代码写的很完美,但是这个是通常是不可能的,所以需要一步一步来,首先把基本的逻辑点写出来,然后一点一点的改进完善,最终的成品就会变得完美。所以就需要你不断对代码进行重构,这样子才可以写出好的代码,切记不要偷懒而不愿意对代码重写重构,还有,学习算法是需要你的决心和毅力,千万不要半途而废

    展开全文
  • 使用数组来实现循环队列

    千次阅读 2020-06-15 09:47:16
    使用数组来实现循环队列 队列 我们知道,在计算机科学中,程序本质上就是数据结构加上算法。数据结构是计算机存储、组织数据的方式。一般来讲,数据结构按照数据的逻辑结构分为线性结构和非线性结构两种。几乎所有的...


    使用数组来实现循环队列

    队列

    我们知道,在计算机科学中,程序本质上就是数据结构加上算法。数据结构是计算机存储、组织数据的方式。一般来讲,数据结构按照数据的逻辑结构分为线性结构和非线性结构两种。几乎所有的线性结构都是建立在两种最基本的结构上的:内存中连续存储的数组结构以及内存中分散存储的链表结构。

    队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列是先进先出的线性结构,而栈(stack)是先进后出的线性结构。

    队列作为一种线性结构,既可以使用数组来实现,也可以用链表进行实现,本文就用Java语言以数组为基础完成一个循环队列的实现。

    队列的接口

    基于队列的特点,我们简单的为我们的队列创建一个接口,规定该队列需要实现的方法。

    package com.hebin.datastructure.queue;
    
    public interface IQueue {
        public void add(int a);
    
        public int get();
    
        public void show();
    
    }
    

    我们创建的是一个存储int数字的队列,需要有从后端增加数字、从前端取出数字,查看队列元素等方法。

    循环队列的实现

    分析队列和数组的特点,我们知道,数组是无法变更大小的,并且数组元素下标必须从0开始,最大不能大于(数组数量-1)。

    /**
     * 使用数组来实现循环队列,队列本质上是一个数组。
     * 队列的特点是先进先出,后进后出;增加元素添加到队列尾部,取出元素从头部获取。
     */
    public class MyArrayQueue implements IQueue {
        // 队列的最大容量
        private int maxSize;
        // 循环队列的当前容量size;
        private int size;
        //循环队列的队头坐标,每次取出数据,该标志位向后移动一位,位于数组尾部时,移动到数组头部
        private int front;
        //循环队列的队尾坐标,每次增加数据,该标志位向后移动一位,位于数组尾部时,移动到数组头部
        private int end;
        // 队列的本体,是一个数组
        private int[] array;
        
         /**
         * 队列的构造函数
         * @param maxSize 指定队列的最大元素个数
         */
        public MyArrayQueue(int maxSize) {
            // 队列的初始大小为0
            this.size = 0;
            // 给定队列的最大容量
            this.maxSize = maxSize;
            // 为了防止数组越界异常,将数组元素位置array[0]作为冗余位,因此数组大小比队列的最大容量大1位。
            this.array = new int[maxSize + 1];
            // 初始化时,队列的队头和队尾标志位置零,一旦发生添加元素或者取出元素操作之后,这俩标志位将从1到maxSize之间循环变化。
            this.front = 0;
            this.end = 0;
        }
        
            /**
         * 判断循环队列是否已满。
         *
         * @return 如果队列已满,返回true,否则返回false。
         */
        private boolean isFull() {
            if (front == 0) {
                // 如果还未取过元素,那么end==maxsize时,队列已满。
                return end == maxSize;
            }
    
            // 如果队列取过元素,那么front一定不为0,循环队列已满,那么array[end]后一位一定是array[front]。
            return end % maxSize + 1 == front;//%为取模操作
        }
    
        /**
         * 判断队列是否空队列
         * @return 空队列返回true,否则返回false。
         */
        private boolean isEmpty() {
            // 如果队列没有取过元素,那么front=0,若队列是空队列,那么end没有下移,end==front==0.
            // 如果队列取过元素,那么队列的end和front一定不等于0,那么空队列则一定有end==front.
            return end == front;
        }
        
        // 队列方法的实现。
        
         @Override
        public void add(int a) {
            if (isFull()) {
                throw new RuntimeException("队列已满,无法添加数据");
            }
            /* 当队列没有满,添加元素时,首先end向下移动一位,然后给array【end】赋值。
               假如maxsize=3,而end=3,此时添加元素,end下移一位,因为array[0]为冗余位,因此end=1。
            */
            end = end % maxSize + 1;
            array[end] = a;
            // 添加元素后,队列大小加一。
            size++;
        }
    
        @Override
        public int get() {
    
            if (isEmpty()) {
                throw new RuntimeException("队列无元素可取");
            }
            front = front % maxSize + 1;
            int temp = array[front];
            size--;
            return temp;
        }
    
        @Override
        public void show() {
            // 队列有几个元素就打印几次
            if (isEmpty()) {
                System.out.println("队列为空队列");
                return;
            }
    
            // 因为队列初始化时,front为0,因此,为了防止取到array[0],进行判断。
            // 同时,如果front==0,则表明队列还未取过元素,同时队列不为空队列,因此array[1]一定是可以取到元素的。
            int temp = front == 0 ? 1 : front;
            for (int i = 0; i < size; i++) {
                System.out.println("array[" + temp + "]=" + array[temp]);
                temp = temp % maxSize + 1;
            }
        }
    }
    

    上面代码就是循环队列的一个基本实现,为了方便我们测试,在该队列实现类中增加一个main方法测试,如下:

    public class MyArrayQueue implements IQueue {
    
        public static void main(String[] args) {
    
            Scanner scanner = new Scanner(System.in);
            boolean flag = true;
            System.out.println("请输入循环队列的容量:");
            int size = scanner.nextInt();
            MyArrayQueue myArrayQueue = new MyArrayQueue(size);
            while (flag) {
                System.out.println("请输入指令:");
                System.out.println("a 表示增加元素:");
                System.out.println("g 表示取出元素:");
                System.out.println("s 表示显示队列所有元素:");
                System.out.println("e 表示退出程序:");
    
    
                String input = scanner.next();
                switch (input) {
                    case "a": {
                        int ele = scanner.nextInt();
                        myArrayQueue.add(ele);
                        break;
                    }
                    case "s": {
                        myArrayQueue.show();
                        break;
                    }
                    case "g": {
                        int i = myArrayQueue.get();
                        System.out.println(i);
                        break;
                    }
                    case "e":
                        flag = false;
                        break;
                }
            }
    
        }
        // 下面是队列的实现,略
        ...
    }
    
    展开全文
  • C++ 用数组实现一个循环队列,很经典的,大家可以看看。
  • 本篇博客将实现循环队列数组结构,实现功能有入队、出队、计算队列长度、判断队列是否为空、为满等。 队列的初始状态如下: 初始状态时,front=rear=0,size=0。 入队操作示意图如下: 入队时,在数组的rear位置...

    本篇博客将实现循环队列的数组结构,实现功能有入队、出队、计算队列长度、判断队列是否为空、为满等。
    队列的初始状态如下:
    在这里插入图片描述
    初始状态时,front=rear=0,size=0。

    入队操作示意图如下:
    在这里插入图片描述
    入队时,在数组原来的rear位置插入数据,插入数据后将rear+1向后移动一位,同时将队列长度size+1。

    在这里插入图片描述
    如上图所示,当rear已经指向数组最后一个位置时,再进行入队操作,rear将重新回到起始位置0.

    出队操作示意图如下所示:

    在这里插入图片描述
    当要将a元素出队时,原本指向a的front指针将移向下一个元素,同时将size-1。要注意的是这时的a其实还在数组中,只是不在有效区域,即实际存在于队列中的数据是front到rear之间的数组数据,而这时的a不在front到rear之间。

    队列空满示意图如下:
    在这里插入图片描述
    如上图所示队列在空和满时,front和rear指针都将重合,因此将很难通过front和rear指针位置判断队列是空还是满。为了方便判断可以采取用实际队列的长度size来进行判断,即size=0时,队列为空;size=capacity(数组的最大容量)时,队列为满。

    具体实现代码如下:
    1.头文件CircleQueue.h

    #pragma once
    #ifndef CIRCLEQUEUE_H
    #define CIRCLEQUEUE_H
    #define NumOfQueue   10
    
    typedef int ElementType;
    
    struct queue
    {
    	int Capacity;
    	int size;
    	int front;
    	int rear;
    	ElementType* Array;
    };
    
    typedef struct queue* Queue;
    
    Queue CreatQueue();//创建空队列;
    
    int IsEmpty(Queue Q);//判断队列是否为空;
    
    int IsFull(Queue Q);//判断队列是否为满;
    
    void MakeEmpty(Queue Q);//置空
    
    int LengthOfQueue(Queue Q);//计算队列长度
    
    void EnQueue(Queue Q, ElementType data);//入队
    
    void DeQueue(Queue Q);//出队
    
    void PrintQueue(Q);//打印队列
    
    #endif // !CIRCLEQUEUE_H
    
    

    2.源文件CircleQueue.c

    #include<stdio.h>
    #include<malloc.h>
    #include"CircleQueue.h"
    
    
    
    Queue CreatQueue()//创建空队列;
    {
    	Queue Q = malloc(sizeof(struct queue));
    	if (Q == NULL)
    	{
    		printf("out of space!!!");
    		exit(1);
    	}
    
    	Q->Array = malloc(sizeof(ElementType) * NumOfQueue);
    	if (!Q->Array)
    	{
    		printf("out of space!!!");
    		exit(1);
    	}
    
    	Q->front = Q->rear = 0;
    	Q->size = 0;
    	Q->Capacity = NumOfQueue;
    
    
    	return Q;
    }
    
    
    
    int IsEmpty(Queue Q)//判断队列是否为空;
    {
    	return Q->size ==0 ;
    }
    
    
    
    int IsFull(Queue Q)//判断队列是否为满;
    {
    	return Q->size == Q->Capacity;
    }
    
    
    
    void MakeEmpty(Queue Q)//置空
    {
    	Q->front = Q->rear = 0;
    	Q->size = 0;
    }
    
    
    
    int LengthOfQueue(Queue Q)//计算队列长度
    {
    	return Q->size;
    }
    
    
    
    void EnQueue(Queue Q, ElementType data)//入队
    {
    	if (IsFull(Q))
    	{
    		printf("Enqueue Error:the queue is  full !!!");
    		exit(1);
    	}
    
    	Q->Array[Q->rear++] = data;
    	if (Q->rear == Q->Capacity)
    		Q->rear = 0;
    
    	++Q->size;
    }
    
    
    
    void DeQueue(Queue Q)//出队
    {
    	if (IsEmpty(Q))
    	{
    		printf("Dequeue Error: the queue is  empty !!!");
    		exit(1);
    	}
    
    	++Q->front;
    	if (Q->front == Q->Capacity)
    		Q->front = 0;
    	--Q->size;
    }
    
    void PrintQueue(Queue Q)//打印队列
    {
    	if (IsEmpty(Q))
    	{
    		printf("Print warning: the queue is  empty !!!");
    		exit(1);
    	}
    
    	int i = Q->front;
    	if(Q->rear>Q->front)
    	for (; i < Q->rear; i++)
    	{
    		printf("%d ", Q->Array[i]);
    	}
    
    	else
    	for (; i < Q->front+Q->size; i++)
    	{
    			printf("%d ", Q->Array[i%Q->Capacity]);
    	}
    	
    	printf("\n");
    }
    

    3.主程序main.c

    /********************************************************************************************************
    Function:循环队列的数组实现
    Date:2020/06/02
    *********************************************************************************************************/
    
    #include"CircleQueue.h"
    
    
    int main()
    {
    	Queue Q=CreatQueue();//创建一个空队列
    
    	for (int i = 0; i < 10; i++)
    	{
    		EnQueue(Q, i);//入队
    	}
    	PrintQueue(Q);//打印队列
    	printf("the length of the queue is:%d\n", LengthOfQueue(Q));//打印队列长度
    
    
    	for (int i = 0; i < 4; i++)
    	{
    		DeQueue(Q);//出队
    	}
    	PrintQueue(Q);//打印队列
    	printf("the length of the queue is:%d\n", LengthOfQueue(Q));//打印队列长度
    
    
    	for (int i = 0; i < 3; i++)
    	{
    		EnQueue(Q, i+10);//入队
    	}
    	PrintQueue(Q);//打印队列
    	printf("the length of the queue is:%d\n", LengthOfQueue(Q));//打印队列长度
    	
    
    	MakeEmpty(Q);//置空
    	PrintQueue(Q);//打印队列
    	printf("the length of the queue is:%d\n", LengthOfQueue(Q));//打印队列长度
    
    
    	return 0;
    }
    

    4.运行结果
    在这里插入图片描述

    展开全文
  • C语言循环队列数组实现)

    千次阅读 2018-07-16 20:45:39
    #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; typedef struct queue_arr { int * data; int front; int rear;...//初始化队列 que * InitQueue() { que * q = (que *)mal...
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct queue_arr
    {
        int * data;
        int front;
        int rear;
        int count;
    } que;
    
    //初始化队列
    que * InitQueue()
    {
        que * q = (que *)malloc(sizeof(que));
        q->front = 0;
        q->rear = 0;
        q->count = 0;//可用于判断队空、队满
        return q;
    }
    
    //判断队满
    int FullQueue(que * q)
    {
        //设置队列长度为10
        if((q->rear+1)%10 == q->front)
            return 0;
        return 1;
    }
    
    //入队函数
    int EnQueue(que * q, int data)
    {
        if(FullQueue(q) == 0)
        {
            return 1;
        }
        else
        {
            q->data[q->rear] = data;
            q->rear = (q->rear+1)%10;
            q->count++;
            return 0;
        }
    }
    
    //出队函数
    que * DelQueue(que * q, int data)
    {
        que * del = q;
        int tmp = del->front,n = del->count;
        if(q->count == 0)//判断队空
            return q;
    
        while(n)
        {
            n--;
            if(del->data[tmp] == data)
              {
                  del->front = (tmp+1)%10;
                  del->count = n;
                  return del;
              }
            tmp = (tmp+1)%10;
    
        }
    
        return q;
    }
    
    //遍历队列
    
    void Display(que * q)
    {
        int i =q->front;
        while(i != q->rear)
        {
            printf("%d ",q->data[i]);
            i = (i+1)%10;
        }
        if(q->count == 0)
            printf("队列为空!");
        printf("\n");
    }
    //测试代码
    int main()
    {
        que * q;
        int i=10;
        q = InitQueue();
        printf("开始入队\n");
        while(i--)
        {
                if(EnQueue(q,i) == 1)
                printf("队满,不能入队!\n");
                else
                {
                    printf("数字 %d 入队后,队列成员为:",i);
                    Display(q);
                }
        }
        i=10;
        printf("开始出队\n");
        while(i--)
        {
            DelQueue(q,i);
            printf("数字 %d 出队后,队列成员为:",i);
            Display(q);
        }
    }
    

     

    展开全文
  • 二、队列数组实现 1、队列的结构 2、清空队列 3、创建一个初始化队列 4、判断队列是否满 5、入队 6、判断队列是否为空 7、出队操作 一、概述 1、队列ADT 队列(Queue)是只允许在一端进行插入操作,...
  • 循环队列实现使用数组
  • 主要介绍了java数据结构与算法之双向循环队列数组实现方法,结合实例形式分析了双向循环队列的原理与数组实现技巧,并附带说明了该算法的用途,需要的朋友可以参考下
  • 1 循环队列的概念
  • 开始存----------------首次存满-------------------删除后继续添加未存满 第一种情况存满-----第二种情况存满-----加倍空间 空间加倍
  • 使用数组实现循环队列

    千次阅读 2019-08-12 11:11:34
    为了节省空间,这里使用数组实现了更加实用 的循环队列,代码主体和上一篇大多一样,但是涉及到一些细节。 下面是具体的思路: 上一篇中front表示第一个元素前面的位置,rear表示最后一个元素的位置, 但是,在这里...
  • 假设front指向队列的头部,rear指向队列的尾部。 则队列满的条件是:(rear+1)%QueueSize==front 则队列为空的条件为:rear==...则队列数组实现如下: private int[] array; private int front; private int rea...
  • 队列的基本概念 0. 准备 不了解队列基本概念的可以点上方的超链接.
  • 数组实现循环队列

    2021-01-22 22:18:30
    这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用这种方法管理的队列也就称为循环队列。除了一些简单应用之外,真正实用的队列是循环队列。 顺序队列的假溢出:当元素被插
  • 实现队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列数组头上出数据效率会比较低。 1.使用链表实现队列 package queue; public class My...
  • 循环队列和顺序队列  队列的存储实现方式有哪些? 顺序存储(数组)和链式存储(链表),此博文描述的是数组的实现(后续更新链表实现)  代码实现 初始化队列:初始化一个size长度的队列,队列的值都为0 判断队列...
  • 循环队列为充分利用向量空间,克服”假溢出”...循环队列的问题循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列
  • 各自完成插入 10万、20万 条随机数,然后再将这些随机数出队列 ; 测试代码 /** * 测试速度 */ public String testSpeed(Queue&amp;amp;lt;Integer&amp;amp;gt; queue, int num) { long start = ...
  • 数组 头尾节点 2. 插入 3. 判满 需要预留一个位置,用于判断队列是否满了 如上图发现(rear+1)%maxSize == front;不再插入 4. 删除 如上直接移动front,相当于删除了下标0的元素1,此时(rear+1)%maxSize != ...
  • 在哔哩哔哩看视频学的,赫斌老师数据结构入门的内容-b站搜索:av6159200(P47),通过学习循环队列,能独立把赫斌老师教的敲出来,并且自己摸索着实现链式队列. 第三部分最后面有我链式队列的ppt图解下载 二.什么是队列 ...
  • 用数组实现循环队列

    2019-07-07 14:38:01
    //用数组循环队列 void dequeueInit(Dequeue * qu)//初始化循环队列 { qu->_head = qu->_tail = qu->_data;//初始位置,队列为空,队首==队尾==数组的首位置 qu->_size = 0;//此时队列的大小为0 }...
  • 下面小编就为大家分享一篇基于Java数组实现循环队列的两种方法小结,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 下面小编就为大家带来一篇Java用数组实现循环队列的示例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • #include<iostream>using namespace std;#define Maxsize 100class Qune{public: int data[Maxsize]; int front; int rear;};void Qinsert(Qune&A,int x); //入队int Qdelete(Qune&A); //出队int...
  • 配套代码讲解:https://blog.csdn.net/songchuwang1868/article/details/90200251 ...同步队列-无锁队列-循环数组无锁队列 同步队列-无锁队列-循环数组无锁队列 同步队列-无锁队列-循环数组无锁队列

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 172,870
精华内容 69,148
关键字:

循环队列用数组a