1.题目
2.思路一(数组)
通过数组进行模拟,通过操作数组的索引构建一个虚拟的首尾相连的环。再循环队列结构中,设置一个队首head和队尾tail,数组的大小固定为k。
初步分析:存在缺陷
改善假溢出问题:
(1) 用size记录数组长度
(2) 多开辟一块空间
这里,我们选择方案二解决:
我们对取尾进行分析:
3参考代码(数组解决)
typedef struct {
int* a;
int head;//头下标
int tail;//尾的下一个的下标
int k;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
//多开一个空间解决假溢出问题
obj->a = malloc(sizeof(int)*(k +1));
obj->head = obj->tail = 0;
obj->k = k;
return obj;
}
//判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->head == obj->tail;
}
//判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
//模(K+1)解决回绕的问题
return (obj->tail + 1)%(obj->k + 1) == obj->head;
}
//入队列
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj))
return false;
//没满
obj->a[obj->tail] = value;
obj->tail++;
//解决回绕的问题
obj->tail %= (obj->k + 1);
return true;
}
//出队列
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return false;
else
{
++obj->head;
//解决回绕问题
obj->head %= (obj->k + 1);
return true;
}
}
//取头
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
else
return obj->a[obj->head];
}
//取尾
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
else
{
//1
//return obj->tail == 0 ? obj->a[obj->k] : obj->a[obj->tail - 1];
//2
//return obj->a[((obj->tail -1) +(obj->k + 1))%(obj->k + 1)]
//简化后
return obj->a[(obj->tail + obj->k )%(obj->k + 1)];
}
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}
4.思路二(链表)
用单链表实现队列较为简单,入队列时,将新的元素尾插插入到链表的尾部;出队列时,将链表的都节点返回,并将头指针指向下一个节点。
创建循环队列
head:链表的头结点,队列的头结点
tail:链表的尾节点,队列的尾节点
capacity:队列的容量
size:队列当前元素的数量
//创建循环队列
typedef struct {
struct ListNode* head;//队列头节点
struct ListNode* tail;//队列尾节点
int capacity;//队列容量
int size;//队列当前元素数量
} MyCircularQueue;
5.参考代码(链表解决)
//创建循环队列
typedef struct {
struct ListNode* head;//队列头节点
struct ListNode* tail;//队列尾节点
int capacity;//队列容量
int size;//队列当前元素数量
} MyCircularQueue;
//初始化
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->capacity = k;
obj->size = 0;
obj->head = obj->tail = NULL;
return obj;
}
//入队列
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(obj->capacity == obj->size)
return false;
//创建新节点
struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));
newnode->val = value;
newnode->next = NULL;
if(!obj->head)//空链表
{
obj->head = obj->tail = newnode;
}
else//非空链表,尾插
{
obj->tail->next = newnode;
obj->tail = newnode;
}
obj->size++;
return true;
}
//出队列(先入先出)
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(obj->size == 0)
return false;
struct ListNode* node = obj->head;
obj->head = obj->head->next;
obj->size--;
free(node);
return true;
}
//返回队首元素
int myCircularQueueFront(MyCircularQueue* obj) {
if(obj->size == 0)
return -1;
return obj->head->val;
}
//返回队尾元素
int myCircularQueueRear(MyCircularQueue* obj) {
if(obj->size == 0)
return -1;
return obj->tail->val;
}
//判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->size == 0;
}
//判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return obj->size == obj->capacity;
}
//销毁队列
void myCircularQueueFree(MyCircularQueue* obj) {
//一次销毁节点
for(struct ListNode* cur = obj->head;cur;)
{
struct ListNode* node = cur;
cur = cur->next;
free(node);
}
free(obj);
}