数据结构:设计循环队列
这道题让我们设计一个循环队列队尾的下一个元素是队头但不同的是这个循环队列是固定大小的队列满则无法插入元素。我们有两种选择可以设计这个循环队列一种是链表一种是顺序表我们比较一下再实现循环队列上的优劣来决定采用哪种选择。选择哪种底层结构在初始化的时候链表要申请k个结点的空间顺序表只需要申请k个元素的大小从初始化来看顺序表比链表简单。。在入队的时候链表插入一个数据ptail就往后移直到队列满ptail就指向最后一个结点。顺序表入队就入到rear所在的位置rear后移一个当队列满了的时候rear4rear与kk4取模就能回到原来的位置。入队方面这两个差不多。出队的时候链表的phead只需要后移一个就可以了顺序表的front也只需要后移一个就好了也差不多。从这些来看顺序表比链表实现简单所以我们在这使用顺序表来实现循环队列。思路在判断队列是否为空的时候只需要判断frontrear是否成立就好了。但我们发现判断队列满的条件和判空条件一模一样所以我们选择多开一个空间开k1个长度的数组此时队列为满rear4当rear1%k10时队列就为满。然后我们出队一个数据再入队一个5此时队列里面的数据是2 3 4 5然后rear越界了此时rear5我们只需要让rear%k1就可以确保每次入队后rear没有越界了。然后rear为0rear1%k1front也能判断出队列满了说明我们这个判断队列是否满的条件没有问题。我们此时再出队2 3 4 5然后front就会一直后移变成这样子我们发现front也会出现越界的情况所以每次出队后都执行front%k1防止front越界。然后发现rearfront又说明我们的队列判空条件也没有问题。因为在函数中我们要用到大小k所以多定义一个capacity用来表示容量。综合以上分析我们把思路理清楚了可以来实现一下代码了。使用顺序表实现循环队列定义结构体首先是定义结构体我们需要一个指针接收数组首地址队头front队尾rear容量capacity。初始化然后就是初始化这个队列的函数MyCircularQueue* myCircularQueueCreate(int k)我们创建一个结构体类型的指针然后申请结构体大小的空间再用arr接收申请的k1个大小的空间让front0rear0capacityk就好了。判断队列是否为空和为满我们先写判断队列是否为空的函数myCircularQueueIsEmpty(MyCircularQueue* obj)和是否为满的函数myCircularQueueIsFull(MyCircularQueue* obj)。只需要判断表达式rearfront是否为空和表达式rear1%k1front是否为满的结果就好了。入队然后就是入队操作当队为满时则入队失败返回false反之插入元素rear后移一位然后rear和k1取模保证rear不越界。出队然后是出队函数myCircularQueueDeQueue(MyCircularQueue* obj)出队需要判断队列是否为空为空则返回false不为空则执行出队操作front然后front%k1防止越界问题。返回队头接下来是队头函数myCircularQueueFront(MyCircularQueue* obj)如果队列是空返回-1反之直接返回队头就好了。返回队尾然后是队尾函数myCircularQueueRear(MyCircularQueue* obj)如果队列为空返回-1不为空则返回rear前一个位置的元素所以我们定义一个prev来代表队尾位置的元素。但有一种特殊情况当rear0时prev就等于-1了所以当rear0时我们的prev应该等于k这才是队尾元素。代码如下销毁队列最后就是销毁队列了我们之前申请了什么空间就把什么空间释放掉然后指针置为NULL变量都置为0就好了。