LeetCode—设计循环队列(两种方法)

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);
}
相关推荐
七颗糖很甜10 分钟前
“十五五”气象发展规划:聚焦五大核心任务
大数据·python·算法
科研前沿17 分钟前
镜像视界浙江科技有限公司的关键技术突破有哪些?
大数据·人工智能·科技·算法·音视频·空间计算
Fuly102424 分钟前
技术经理面试相关--技术篇
面试·职场和发展
嫩萝卜头儿26 分钟前
2 - 复杂度收尾 + 链表经典OJ
数据结构·算法·链表·复杂度
星马梦缘39 分钟前
算法设计与分析 作业二 答案与解析
算法·图论·dfs·bfs·floyd-warshall·bellman_ford·多源最短路
玛丽莲茼蒿39 分钟前
Leetcode hot100 每日温度【中等】
算法·leetcode·职场和发展
cjp5601 小时前
009.UG二次开发,任务环境草图优化3(高级功能生成直线)
算法
样例过了就是过了1 小时前
LeetCode热题100 分割等和子集
数据结构·c++·算法·leetcode·动态规划
逻辑驱动的ken1 小时前
Java高频面试考点18
java·开发语言·数据库·算法·面试·职场和发展·哈希算法
木木_王1 小时前
嵌入式Linux学习 | 数据结构 (Day05) 栈与队列详解(原理 + C 语言实现 + 实战实验 + 易错点剖析)
linux·c语言·开发语言·数据结构·笔记·学习