当前位置: 首页 > news >正文

网站运行环境建设方案南京做网站南京乐识赞

网站运行环境建设方案,南京做网站南京乐识赞,阿里绿网网站违规,comsenzexp wordpress一、队列基础概念 队列是一种 先进先出(FIFO) 的线性结构,操作受限,仅允许在队尾插入(入队),队头删除(出队)。 二、顺序队列 1. 结构定义 存储方式:基于数…

一、队列基础概念

队列是一种 先进先出(FIFO) 的线性结构,操作受限,仅允许在队尾插入(入队),队头删除(出队)。


二、顺序队列

1. 结构定义
  • 存储方式:基于数组,frontrear分别指向队头和队尾。
  • 代码实现
    #define MAX_SIZE 100
    typedef struct {int data[MAX_SIZE];int front;  // 队头指针int rear;   // 队尾指针
    } SeqQueue;
    
2. 优缺点
  • 优点:实现简单,访问速度快(数组随机访问)。
  • 缺点:固定大小导致空间浪费或溢出;出队需移动元素,时间复杂度高。
3. 核心操作代码
  • 入队(时间复杂度O(1)):

    int EnQueue(SeqQueue *q, int x) {if (q->rear == MAX_SIZE) {printf("队列已满");return 0;}q->data[q->rear++] = x;return 1;
    }
    
  • 出队(时间复杂度O(n),需移动元素):

    int DeQueue(SeqQueue *q, int *x) {if (q->front == q->rear) {printf("队列为空");return 0;}*x = q->data[0];for (int i = 0; i < q->rear - 1; i++) q->data[i] = q->data[i + 1]; // 元素前移q->rear--;return 1;
    }
    

三、循环队列

1. 结构定义
  • 核心思想:数组首尾相连,通过取模运算实现循环,解决“假溢出”。
  • 判空/满条件
    • 队空:front == rear
    • 队满:(rear + 1) % MAX_SIZE == front(牺牲一个存储单元)。
2. 优缺点
  • 优点:空间利用率高,入队/出队O(1)。
  • 缺点:容量固定,实现复杂(需处理模运算)。
3. 核心操作代码
typedef struct {int data[MAX_SIZE];int front, rear;
} CircularQueue;// 入队
int EnQueue(CircularQueue *q, int x) {if ((q->rear + 1) % MAX_SIZE == q->front) {printf("队列已满");return 0;}q->data[q->rear] = x;q->rear = (q->rear + 1) % MAX_SIZE;return 1;
}// 出队
int DeQueue(CircularQueue *q, int *x) {if (q->front == q->rear) {printf("队列为空");return 0;}*x = q->data[q->front];q->front = (q->front + 1) % MAX_SIZE;return 1;
}

四、双向队列(Deque)

1. 结构定义
  • 特点:允许两端插入和删除,结合队列和栈的特性。
  • 实现方式:数组或链表(常用循环数组)。
2. 优缺点
  • 优点:操作灵活,支持随机访问(数组实现)。
  • 缺点:数组实现需处理扩容,链表实现需额外指针开销。
3. 核心操作代码(数组实现)
#define DEQUE_SIZE 100
typedef struct {int data[DEQUE_SIZE];int front, rear;
} Deque;// 队头插入
int PushFront(Deque *dq, int x) {if ((dq->front - 1 + DEQUE_SIZE) % DEQUE_SIZE == dq->rear) {printf("队列已满");return 0;}dq->front = (dq->front - 1 + DEQUE_SIZE) % DEQUE_SIZE;dq->data[dq->front] = x;return 1;
}// 队尾删除
int PopRear(Deque *dq, int *x) {if (dq->front == dq->rear) {printf("队列为空");return 0;}*x = dq->data[(dq->rear - 1 + DEQUE_SIZE) % DEQUE_SIZE];dq->rear = (dq->rear - 1 + DEQUE_SIZE) % DEQUE_SIZE;return 1;
}

五、时间复杂度分析

操作顺序队列循环队列双向队列(数组)
入队(尾部)O(1)O(1)O(1)
出队(头部)O(n)O(1)O(1)
随机访问O(1)O(1)O(1)

解释:顺序队列出队需移动元素,故为O(n);循环队列通过模运算避免移动,所有操作O(1)。


六、考研高频考点

  1. 循环队列的判空/满条件(如:(rear + 1) % size == front)。
  2. 双端队列的应用:滑动窗口、页面置换算法。
  3. 队列与层次遍历(BFS) :求二叉树层数、最短路径。

七、经典算法题解析(补充至3题)


题目1:用队列实现栈(LeetCode 225)

问题描述
使用两个队列实现一个后进先出(LIFO)的栈,并支持普通栈的全部操作(pushpoptopempty)。

解法思路

  • 核心矛盾:队列是FIFO,而栈是LIFO。
  • 关键操作:每次push新元素时,先将元素加入辅助队列,再将主队列中的元素依次移入辅助队列,最后交换两个队列的角色。
  • 时间复杂度push为O(n),其他操作为O(1)。

C语言代码(基于循环队列实现):

#include <stdlib.h>
#define MAX_SIZE 100typedef struct {CircularQueue q1;  // 主队列CircularQueue q2;  // 辅助队列
} MyStack;MyStack* myStackCreate() {MyStack *stack = (MyStack*)malloc(sizeof(MyStack));stack->q1.front = stack->q1.rear = 0;stack->q2.front = stack->q2.rear = 0;return stack;
}void myStackPush(MyStack* obj, int x) {// 先将元素加入辅助队列q2EnQueue(&obj->q2, x);// 将q1中的元素全部转移到q2while (!QueueEmpty(&obj->q1)) {int val;DeQueue(&obj->q1, &val);EnQueue(&obj->q2, val);}// 交换q1和q2的角色CircularQueue temp = obj->q1;obj->q1 = obj->q2;obj->q2 = temp;
}int myStackPop(MyStack* obj) {int val;DeQueue(&obj->q1, &val);return val;
}int myStackTop(MyStack* obj) {return obj->q1.data[obj->q1.front];
}int myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1);
}

易错点

  • 队列判空条件错误:未正确实现QueueEmpty函数,导致逻辑混乱。
  • 未及时交换队列:在push操作后必须交换队列,否则后续操作会出错。

题目2:二叉树的层序遍历(LeetCode 102)

问题描述
给定一个二叉树,返回其按层序遍历得到的节点值(即逐层从左到右访问所有节点)。

解法思路

  • BFS框架:用队列存储每层的节点,每次处理一层节点时,记录当前队列长度(即该层节点数),依次出队并将子节点入队。
  • 时间复杂度:O(n),每个节点进出队列一次。

C语言代码(需结合队列结构):

typedef struct TreeNode {int val;struct TreeNode *left, *right;
} TreeNode;int** levelOrder(TreeNode* root, int* returnSize, int** returnColumnSizes) {if (!root) return NULL;// 初始化队列CircularQueue q;q.front = q.rear = 0;EnQueue(&q, root);int**res = (int**)malloc(sizeof(int*) * MAX_SIZE);*returnColumnSizes = (int*)malloc(sizeof(int) * MAX_SIZE);*returnSize = 0;while (!QueueEmpty(&q)) {int level_size = (q.rear - q.front + MAX_SIZE) % MAX_SIZE;res[*returnSize] = (int*)malloc(sizeof(int) * level_size);(*returnColumnSizes)[*returnSize] = level_size;for (int i = 0; i < level_size; i++) {TreeNode* node;DeQueue(&q, &node);  // 出队当前层节点res[*returnSize][i] = node->val;if (node->left) EnQueue(&q, node->left);  // 左子节点入队if (node->right) EnQueue(&q, node->right); // 右子节点入队}(*returnSize)++;}return res;
}

关键点解析

  • 记录每层大小level_size用于确定当前层的节点数量,确保结果数组正确分配内存。
  • 子节点入队条件:需判断子节点非空再入队,避免队列中混入空指针。

题目3:设计循环双端队列(LeetCode 641)

问题描述
设计实现一个循环双端队列,支持以下操作:

  • insertFront():在队头添加元素。
  • insertLast():在队尾添加元素。
  • deleteFront():删除队头元素。
  • deleteLast():删除队尾元素。
  • getFront():获取队头元素。
  • getRear():获取队尾元素。
  • isEmpty():检查队列是否为空。
  • isFull():检查队列是否已满。

解法思路

  • 循环数组实现:利用取模运算处理索引循环,牺牲一个存储单元区分队空和队满。
  • 边界处理:插入和删除时需分别处理frontrear的移动方向。

C语言代码

typedef struct {int *data;int front, rear;int capacity;
} MyCircularDeque;MyCircularDeque* myCircularDequeCreate(int k) {MyCircularDeque* dq = (MyCircularDeque*)malloc(sizeof(MyCircularDeque));dq->data = (int*)malloc(sizeof(int) * (k + 1)); // 多分配一个空间用于判满dq->front = dq->rear = 0;dq->capacity = k + 1;return dq;
}int myCircularDequeInsertFront(MyCircularDeque* obj, int value) {if (myCircularDequeIsFull(obj)) return 0;obj->front = (obj->front - 1 + obj->capacity) % obj->capacity; // 队头前移obj->data[obj->front] = value;return 1;
}int myCircularDequeInsertLast(MyCircularDeque* obj, int value) {if (myCircularDequeIsFull(obj)) return 0;obj->data[obj->rear] = value;obj->rear = (obj->rear + 1) % obj->capacity; // 队尾后移return 1;
}int myCircularDequeDeleteFront(MyCircularDeque* obj) {if (myCircularDequeIsEmpty(obj)) return 0;obj->front = (obj->front + 1) % obj->capacity;return 1;
}int myCircularDequeDeleteLast(MyCircularDeque* obj) {if (myCircularDequeIsEmpty(obj)) return 0;obj->rear = (obj->rear - 1 + obj->capacity) % obj->capacity;return 1;
}int myCircularDequeGetFront(MyCircularDeque* obj) {return myCircularDequeIsEmpty(obj) ? -1 : obj->data[obj->front];
}int myCircularDequeGetRear(MyCircularDeque* obj) {return myCircularDequeIsEmpty(obj) ? -1 : obj->data[(obj->rear - 1 + obj->capacity) % obj->capacity];
}int myCircularDequeIsEmpty(MyCircularDeque* obj) {return obj->front == obj->rear;
}int myCircularDequeIsFull(MyCircularDeque* obj) {return (obj->rear + 1) % obj->capacity == obj->front;
}

易错点

  • 索引计算错误:在队头插入时,front应前移(front - 1),而非后移。
  • 判满条件错误:必须牺牲一个存储单元,否则队空和队满条件会冲突。

八、易错点总结

  1. 循环队列的判满条件:必须牺牲一个存储单元,否则与判空条件冲突。
  2. 指针初始值frontrear通常初始化为0,但需根据实现方式调整。
  3. 边界检查:操作前必须检查队列是否为空/满,避免溢出或空指针。

九、解题方法论

  1. 选择合适结构:空间固定用循环队列,动态扩展用链队列。
  2. BFS模板:队列维护当前层节点,逐层扩展。
  3. 滑动窗口:双端队列维护极值,减少重复计算。

附:考研复习建议

  • 重点掌握:循环队列的判空判满、双端队列的应用。
  • 典型习题:设计循环队列(LeetCode 622)、二叉树的右视图(BFS应用)。
  • 易错题:循环队列长度计算 (rear - front + size) % size

通过系统梳理和代码实践,可深入理解队列的核心思想与应用场景。

http://www.dtcms.com/a/528699.html

相关文章:

  • [sam2图像分割] 图像编码器 | Hiera FPN Neck
  • 基于 Dify 的 Excel 测试用例自动化脚本生成工作流开发
  • Photoshop - Photoshop 工具栏(16)画笔工具
  • 深圳网站建设信科便宜设计欣赏网
  • CSS简介(本文为个人学习笔记,内容整理自哔哩哔哩UP主【非学者勿扰】的公开课程。 > 所有知识点归属原作者,仅作非商业用途分享)
  • css之box-sizing属性
  • 【设计模式笔记02】:面向对象设计原则-开闭原则
  • 用于电动汽车的永磁同步电机调速系统建模与仿真(论文+)
  • 校区网站建设网站建设区别
  • 网站建设是什么科目注册企业邮箱免费
  • 长短期记忆网络(LSTM)与门控循环单元(GRU)详解
  • 研究报告:系统排列(Systemic Constellations)的原理、理论体系及文献综述
  • 尚庭公寓学习笔记
  • Unity单例模式基类全解析
  • 餐饮行业做网站的数据ctoc网站有哪些
  • 深圳建设局网站投诉电话淄博网站建设优化公司
  • 久治县网站建设公司东莞人才网最新招聘信息
  • MySQL OCP认证、Oracle OCP认证
  • 深入探讨HarmonyOS中ListItem的滑动操作:从基础实现到高级分布式交互
  • Eclipse Uninstall Software
  • 广东南方通信建设有限公司官方网站合肥网站建设的价格
  • C语言<<超全.超重要>>知识点总结
  • 购物网站开发的业务需求分析做钢材什么网站好
  • Spring框架常用注解全面详解与技术实践
  • 机器学习三要素
  • synchronized锁优化与升级机制
  • 设计公司网站运营wordpress+编辑模板
  • URL下载网络资源
  • Spring Bean注解终极指南:从入门到精通
  • wordpress旅游类网站深圳哪里做网站