数据结构——链式队列和循环队列

目录

引言

队列的定义

队列的分类

1.单链表实现

2.数组实现

队列的功能

队列的声明

1.链式队列

2.循环队列

队列的功能实现

1.队列初始化

(1)链式队列

(2)循环队列

(3)复杂度分析

2.判断队列是否为空

(1)链式队列

(2)循环队列

(3)复杂度分析

3.判断队列是否已满

(1)链式队列

(2)循环队列

(3)复杂度分析

4.返回队头元素

(1)链式队列

(2)循环队列

(3)复杂度分析

5.返回队尾元素

(1)链式队列

(2)循环队列

(3)复杂度分析

6.返回队列大小

(1)链式队列

(2)循环队列

(3)复杂度分析

7.元素入队列

(1)链式队列

(2)循环队列

(3)复杂度分析

8.元素出队列

(1)链式队列

(2)循环队列

(3)复杂度分析

9.打印队列元素

(1)链式队列

(2)循环队列

(3)复杂度分析

10.销毁队列

(1)链式队列

(2)循环队列

(3)复杂度分析

链式队列和循环队列的对比

完整代码

1.链式队列

2.循环队列

结束语


引言

在 数据结构——栈 中我们学习了栈的相关知识,今天我们接着来学习数据结构——队列。

队列的定义

队列(Queue)是一种先进先出(FIFO, First-In-First-Out)的线性数据结构。它只允许在队列的一端(队尾)进行插入(enqueue)操作,而在另一端(队头)进行删除(dequeue)操作。这种操作方式确保了队列中元素的顺序性,即最先进入队列的元素将最先被移除。

如图所示:

队头(Front):队头是指队列中允许删除操作的一端。也就是说,队列中的元素将按照它们被添加到队列中的顺序,从队头开始被逐一移除。

队尾(Rear):队尾是指队列中允许插入操作的一端。新元素将被添加到队尾,以保持队列的先进先出(FIFO)特性。

队列的分类

队列与栈类似,同样可以用两种方式实现。分别是单链表和数组。接下来我们来分析一下如何使用两种方法实现队列。

1.单链表实现

我们可以将链表的头节点与尾节点分别作为队列的队首与队尾,这样我们就能用两个指针来对其进行操作。

如下图所示:

2.数组实现

问题一:

在使用数组实现队列时,可能会出现“假溢出”的情况。这是因为数组的头部和尾部是固定的,当队列的尾部达到数组的末尾时,即使数组的头部还有很多空闲空间,也无法再向队列中添加新元素。这种情况下,队列虽然看起来是满的,但实际上还有很多空间没有被利用。

解决方法:

我们可以将数组相接变成循环数组。

问题二:

变成循环数组又会出现新的问题:当队首与队尾下标都指向同一个节点时,这个队列是还是呢?

解决方法:

多使用一个空间便于我们区分队空和队满。若队列不为空,让队尾下标指向队尾的下一个位置。我们约定以队头指针在队尾指针的下一位置作为队满的标志,即Queue->rear+1=Queue->front

如下图所示:

队满状态:

队列的功能

1.队列的初始化。

2.判断队列是否为空。

3.判断队列是否已满。

4.返回队头元素。

5.返回队尾元素

6.返回队列的大小。

7.元素入队列。

8.元素出队列。

9.打印队列的元素。

10.销毁队列。

队列的声明

1.链式队列

typedef int QDataType;typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;typedef struct Queue
{QNode* front;QNode* rear;int size;
}Queue;

2.循环队列

typedef int QDataType;#define MAXSIZE 30    //定义队列的最大值
typedef struct
{QDataType* data;int front;    //头指针int rear;     //尾指针
}Queue;

队列的功能实现

1.队列初始化

给队列中的各个元素给定值,以免出现随机值。

(1)链式队列
//初始化
void QueueInit(Queue* q)
{assert(q);q->front = NULL;q->rear = NULL;q->size = 0;
}
(2)循环队列
//初始化
void QueueInit(Queue* q)
{// 为队列的数据存储空间分配内存。q->data = (QDataType*)malloc(sizeof(QDataType) * MAXSIZE);if (q->data == NULL){perror("malloc fail:");return;}// 初始化队首和队尾指针为0,表示队列为空q->front = q->rear = 0;
}
(3)复杂度分析

时间复杂度:由于链式队列和循环队列花费时间都是一个常数,因此时间复杂度为O(1)。

空间复杂度:由于链式队列花费的是一个固定大小的空间,因此空间复杂度为O(1)。循环队列需要开辟整个队列的大小,因此空间复杂度为O(N)。

2.判断队列是否为空

(1)链式队列

判断size是否为0即可。

代码如下:

//判断队列是否为空
bool QueueEmpty(Queue* q)
{assert(q);return q->size == 0;
}
(2)循环队列

判断front是否等于rear即可。

代码如下:

//判断队列是否为空
bool QueueEmpty(Queue* q)
{assert(q);return q->front == q->rear;
}
(3)复杂度分析

时间复杂度:由于链式队列和循环队列花费时间都是一个常数,因此时间复杂度为O(1)。

空间复杂度:由于链式队列和循环队列花费空间都是一个常数,因此空间复杂度为O(1)。

3.判断队列是否已满

(1)链式队列

链式队列不需要判断队列是否已满。

(2)循环队列

循环队列判断是否已满需要进行一些特殊处理。

代码如下:

//判断队列是否已满
bool QueueFull(Queue* q)
{assert(q);// 取模操作是避免越界return q->front == (q->rear + 1) % MAXSIZE;
}
(3)复杂度分析

时间复杂度:由于循环队列花费时间是一个常数,因此时间复杂度为O(1)。

空间复杂度:循环队列花费的是一个固定大小的空间,所以空间复杂度为O(1)。

4.返回队头元素

(1)链式队列
//读取队头数据
QDataType QueueFront(Queue* q)
{assert(q);assert(q->front);return q->front->val;
}
(2)循环队列
//读取队头数据
QDataType QueueFront(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->data[q->front];
}
(3)复杂度分析

时间复杂度:由于链式队列和循环队列花费时间都是一个常数,因此时间复杂度为O(1)。

空间复杂度:由于链式队列和循环队列花费空间都是一个常数,因此空间复杂度为O(1)。

5.返回队尾元素

(1)链式队列
//读取队尾数据
QDataType QueueBack(Queue* q)
{assert(q);assert(q->rear);return q->rear->val;
}
(2)循环队列
//读取队尾数据
QDataType QueueBack(Queue* q)
{assert(q);assert(!QueueEmpty(q));// 当rear为0时,rear-1会导致负数索引,这在数组中是无效的  // 通过加上MAXSIZE并取模MAXSIZE,我们可以确保索引始终在有效范围内  // 这里(q->rear - 1 + MAXSIZE) % MAXSIZE计算的是队尾元素的索引return q->data[(q->rear - 1 + MAXSIZE) % MAXSIZE];
}
(3)复杂度分析

时间复杂度:由于链式队列和循环队列花费时间都是一个常数,因此时间复杂度为O(1)。

空间复杂度:由于链式队列和循环队列花费空间都是一个常数,因此空间复杂度为O(1)。

6.返回队列大小

(1)链式队列

链式队列求队列大小很简单,直接返回size即可。

代码如下:

//统计队列数据个数
int QueueSize(Queue* q)
{assert(q);return q->size;
}
(2)循环队列

我们来分析一下:

像这个可以使用rear-front求出队列的大小。但是要知道,这是个循环队列,rear时=是可以跑到front之后的,如下图所示:

解决方法:rear减去front之后加个MAXSIZE就好了。

代码如下:

//统计队列数据个数
int QueueSize(Queue* q)
{assert(q);return (q->rear - q->front + MAXSIZE) % MAXSIZE;
}
(3)复杂度分析

时间复杂度:由于链式队列和循环队列花费时间都是一个常数,因此时间复杂度为O(1)。

空间复杂度:由于链式队列和循环队列花费空间都是一个常数,因此空间复杂度为O(1)。

7.元素入队列

(1)链式队列

链式队列元素入队需要判断队列是否为空的情况。

代码如下:

//队尾插入
void QueuePush(Queue* q, QDataType x)
{assert(q);QNode* newNode = (QNode*)malloc(sizeof(QNode));if (newNode == NULL){perror("malloc fail");return;}newNode->next = NULL;newNode->val = x;// 如果队列为空 if (q->rear == NULL){// 新节点既是队首也是队尾q->front = q->rear = newNode;}else{// 将当前队尾节点的next指向新节点q->rear->next = newNode;// 更新队尾指针为新节点q->rear = newNode;}q->size++;
}
(2)循环队列

取模操作不能少,确保不会越界。

//队尾插入
void QueuePush(Queue* q, QDataType x)
{assert(q);if (QueueFull){printf("队列已满\n");return;}q->data[q->rear] = x;// rear指针向后移动// (q->rear + 1) % MAXSIZE这段代码// 确保了rear指针的值始终在0到MAXSIZE-1的范围内循环q->rear = (q->rear + 1) % MAXSIZE;
}
(3)复杂度分析

时间复杂度:由于链式队列和循环队列花费时间都是一个常数,因此时间复杂度为O(1)。

空间复杂度:由于链式队列和循环队列花费空间都是一个常数,因此空间复杂度为O(1)。

8.元素出队列

(1)链式队列
//队头删除
void QueuePop(Queue* q)
{assert(q);assert(q->size != 0);// 检查队列中是否只有一个节点if (q->front->next == NULL){free(q->front);// 队列变为空,队首和队尾指针都设置为NULLq->front = q->rear = NULL;}// 多个节点else{// 保存下一个节点的指针QNode* next = q->front->next;// 释放队首节点free(q->front);// 更新队首指针为下一个节点q->front = next;}q->size--;
}
(2)循环队列
//队头删除
void QueuePop(Queue* q)
{assert(q);assert(!QueueEmpty(q));// front指针向后移动// (q->front + 1) % MAXSIZE这段代码// 确保了front指针的值始终在0到MAXSIZE-1的范围内循环q->front = (q->front + 1) % MAXSIZE;
}
(3)复杂度分析

时间复杂度:由于链式队列和循环队列花费时间都是一个常数,因此时间复杂度为O(1)。

空间复杂度:由于链式队列和循环队列花费空间都是一个常数,因此空间复杂度为O(1)。

9.打印队列元素

(1)链式队列
//打印队列元素
void QueuePrint(Queue* q)
{assert(q);QNode* cur = q->front;QNode* tail = q->rear;printf("队头->");while (cur != tail->next){printf("%d->", cur->val);cur = cur->val;}printf("队尾\n");
}
(2)循环队列
//打印队列元素
void QueuePrint(Queue* q)
{assert(q);int cur = q->front;printf("队头->");while (cur != q->rear){printf("%d->", q->data[cur]);// 避免越界cur = (cur + 1) % MAXSIZE;}printf("队尾\n");
}
(3)复杂度分析

时间复杂度:由于链式队列和循环队列都需要遍历整个队列,因此时间复杂度为O(n)。

空间复杂度:由于链式队列和循环队列花费空间都是一个常数,因此空间复杂度为O(1)。

10.销毁队列

(1)链式队列
//销毁
void QueueDestroy(Queue* q)
{assert(q);QNode* cur = q->front;while (cur){QNode* next = cur->next;free(cur);cur = next;}q->front = q->rear = NULL;q->size = 0;
}
(2)循环队列
//销毁
void QueueDestroy(Queue* q)
{assert(q);free(q->data);q->data = NULL;q->front = q->rear = 0;
}
(3)复杂度分析

时间复杂度:由于链式队列需要遍历整个队列,因此时间复杂度为O(n)。循环队列花费时间是一个常数,因此时间复杂度为O(1)。

空间复杂度:由于链式队列和循环队列花费空间都是一个常数,因此空间复杂度为O(1)。

链式队列和循环队列的对比

链式列表循环列表
数据结构使用链表实现,队列中的每个元素都是一个链表节点,节点之间通过指针相连使用数组实现,但在逻辑上将数组的头尾相连,形成一个环形结构。
内存管理出队或清空队列时需要释放链表节点的内存无需手动释放内存,因为队列元素存储在数组中,数组的内存由系统自动管理
时间效率由于使用头指针与尾指针,因此链式队的出队与入队的时间都相对较小循环队列是基于数组实现的,支持下标的随机访问,所以时间消耗并不大
空间效率空间使用灵活,可以根据需要动态地增加或减少内存分配空间使用相对固定,需要预先定义最大容量。如果队列的实际大小远小于最大容量,则会造成空间浪费

完整代码

1.链式队列

Queue.h

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int QDataType;typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;typedef struct Queue
{QNode* front;QNode* rear;int size;
}Queue;//初始化
void QueueInit(Queue* q);
//销毁
void QueueDestroy(Queue* q);//队尾插入
void QueuePush(Queue* q, QDataType x);
//队头删除
void QueuePop(Queue* q);//读取队头数据
QDataType QueueFront(Queue* q);
//读取队尾数据
QDataType QueueBack(Queue* q);//统计队列数据个数
int QueueSize(Queue* q);
//判断队列是否为空
bool QueueEmpty(Queue* q);//打印队列元素
void QueuePrint(Queue* q);

Queue.c

#define _CRT_SECURE_NO_WARNINGS 1#include"Queue.h"//初始化
void QueueInit(Queue* q)
{assert(q);q->front = NULL;q->rear = NULL;q->size = 0;
}//销毁
void QueueDestroy(Queue* q)
{assert(q);QNode* cur = q->front;while (cur){QNode* next = cur->next;free(cur);cur = next;}q->front = q->rear = NULL;q->size = 0;
}//队尾插入
void QueuePush(Queue* q, QDataType x)
{assert(q);QNode* newNode = (QNode*)malloc(sizeof(QNode));if (newNode == NULL){perror("malloc fail");return;}newNode->next = NULL;newNode->val = x;// 如果队列为空 if (q->rear == NULL){// 新节点既是队首也是队尾q->front = q->rear = newNode;}else{// 将当前队尾节点的next指向新节点q->rear->next = newNode;// 更新队尾指针为新节点q->rear = newNode;}q->size++;
}//队头删除
void QueuePop(Queue* q)
{assert(q);assert(q->size != 0);// 检查队列中是否只有一个节点if (q->front->next == NULL){free(q->front);// 队列变为空,队首和队尾指针都设置为NULLq->front = q->rear = NULL;}// 多个节点else{// 保存下一个节点的指针QNode* next = q->front->next;// 释放队首节点free(q->front);// 更新队首指针为下一个节点q->front = next;}q->size--;
}//读取队头数据
QDataType QueueFront(Queue* q)
{assert(q);assert(q->front);return q->front->val;
}//读取队尾数据
QDataType QueueBack(Queue* q)
{assert(q);assert(q->rear);return q->rear->val;
}//统计队列数据个数
int QueueSize(Queue* q)
{assert(q);return q->size;
}//判断队列是否为空
bool QueueEmpty(Queue* q)
{assert(q);return q->size == 0;
}//打印队列元素
void QueuePrint(Queue* q)
{assert(q);QNode* cur = q->front;QNode* tail = q->rear;printf("队头->");while (cur != tail->next){printf("%d->", cur->val);cur = cur->val;}printf("队尾\n");
}

2.循环队列

 Queue.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef int QDataType;#define MAXSIZE 30
typedef struct
{QDataType* data;int front;int rear;
}Queue;//初始化
void QueueInit(Queue* q);
//销毁
void QueueDestroy(Queue* q);//队尾插入
void QueuePush(Queue* q, QDataType x);
//队头删除
void QueuePop(Queue* q);//读取队头数据
QDataType QueueFront(Queue* q);
//读取队尾数据
QDataType QueueBack(Queue* q);//统计队列数据个数
int QueueSize(Queue* q);
//判断队列是否为空
bool QueueEmpty(Queue* q);//打印队列元素
void QueuePrint(Queue* q);//判断队列是否已满
bool QueueFull(Queue* q);

Queue.h

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"//初始化
void QueueInit(Queue* q)
{// 为队列的数据存储空间分配内存。q->data = (QDataType*)malloc(sizeof(QDataType) * MAXSIZE);if (q->data == NULL){perror("malloc fail:");return;}// 初始化队首和队尾指针为0,表示队列为空q->front = q->rear = 0;
}//销毁
void QueueDestroy(Queue* q)
{assert(q);free(q->data);q->data = NULL;q->front = q->rear = 0;
}//队尾插入
void QueuePush(Queue* q, QDataType x)
{assert(q);if (QueueFull(q)){printf("队列已满\n");return;}q->data[q->rear] = x;// rear指针向后移动// (q->rear + 1) % MAXSIZE这段代码// 确保了rear指针的值始终在0到MAXSIZE-1的范围内循环q->rear = (q->rear + 1) % MAXSIZE;
}//队头删除
void QueuePop(Queue* q)
{assert(q);assert(!QueueEmpty(q));// front指针向后移动// (q->front + 1) % MAXSIZE这段代码// 确保了front指针的值始终在0到MAXSIZE-1的范围内循环q->front = (q->front + 1) % MAXSIZE;
}//读取队头数据
QDataType QueueFront(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->data[q->front];
}
//读取队尾数据
QDataType QueueBack(Queue* q)
{assert(q);assert(!QueueEmpty(q));// 当rear为0时,rear-1会导致负数索引,这在数组中是无效的  // 通过加上MAXSIZE并取模MAXSIZE,我们可以确保索引始终在有效范围内  // 这里(q->rear - 1 + MAXSIZE) % MAXSIZE计算的是队尾元素的索引return q->data[(q->rear - 1 + MAXSIZE) % MAXSIZE];
}//统计队列数据个数
int QueueSize(Queue* q)
{assert(q);return (q->rear - q->front + MAXSIZE) % MAXSIZE;
}//判断队列是否为空
bool QueueEmpty(Queue* q)
{assert(q);return q->front == q->rear;
}//判断队列是否已满
bool QueueFull(Queue* q)
{assert(q);return q->front == (q->rear + 1) % MAXSIZE;
}//打印队列元素
void QueuePrint(Queue* q)
{assert(q);int cur = q->front;printf("队头->");while (cur != q->rear){printf("%d->", q->data[cur]);// 避免越界cur = (cur + 1) % MAXSIZE;}printf("队尾\n");
}

结束语

本篇博客大致介绍了数据结构——队列的内容。

感谢每位能点进来阅读的大佬们!!!

十分感谢!!!

求点赞收藏关注!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/50999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

26.删除有序数组中的重复项---力扣

题目链接&#xff1a; . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/remove-duplicates-from-sorted-array/descript…

仿Muduo库实现高并发服务器——Server.hpp框架的简单描述

EventLoop模块在本项目中的简单使用&#xff1a; 下面这张图 是channel模块&#xff0c;poller模块&#xff0c;TimerWheel模块&#xff0c;EventLoop模块&#xff0c;LoopThreadPool模块进行组合。便于大家对这个项目的理解&#xff0c;因为代码看起来挺复杂的。 下面这个图&…

招募活动投稿展示 | 感受科技温度,从一个 LLM 应用开始

活动介绍 谷歌开发者招募活动是专为 Google 技术的爱好者及开发者们开展的活动&#xff0c;旨在鼓励大家通过多种形式 (文章/视频/coding 等) 创作与 Google 技术相关的讲解分享、实践案例或活动感受等内容&#xff0c;展示代码、框架、平台在真实世界中的生动表现&#xff0c;…

详解Spring Bean的生命周期

详解Bean的生命周期 前言 在我们没有使用Spring框架之前&#xff0c;创建对象一般都是使用new关键字进行创建&#xff0c;当然除了new关键字外&#xff0c;还有 运用反射手段&#xff0c;使用Class类的newInstance方法 或者 Constructor类中的newInstance方法使用clone方法使…

JavaScript语法基础之DOM基础

目录 1. DOM 基础 1.1. DOM 是什么&#xff1f; 1.1.1. DOM 对象 1.1.2. DOM 结构 1.2. 节点类型 1.3. 获取元素 1.3.1. getElementById() 1.3.2. getElementsByTagName() 1.3.3. getElementsByClassName() 1.3.4. getElementsByName() 1.4.如何去操作对象 修改属性…

IP SSL证书的未来趋势:适应不断变化的安全挑战

随着网络攻击手段的不断进化和用户对隐私保护意识的增强&#xff0c;IP SSL证书作为保障网络安全的关键组件之一&#xff0c;也在不断地发展和完善。本文将探讨IP SSL证书的未来趋势&#xff0c;以及如何适应这些不断变化的安全挑战。 当前状况与挑战 网络安全意识提升&#…

ARM 裸机与 Linux 驱动对比及 Linux 内核入门

目录 ARM裸机代码和驱动的区别 Linux系统组成 内核五大功能 设备驱动分类 内核类型 驱动模块 驱动模块示例 Makefile配置 命令 编码辅助工具 内核中的打印函数 printk 函数 修改打印级别 ​编辑 打印级别含义 驱动多文件编译 示例 模块传递参数 命令行传递参数…

python-docx 实现 Word 办公自动化

前言&#xff1a;当我们需要批量生成一些合同文件或者简历等。如果手工处理对于我们来说不仅工作量巨大&#xff0c;而且难免会出现一些问题。这个时候运用python处理word实现自动生成文件可极大的提高工作效率。 python-docx是python的第三方插件&#xff0c;用来处理word文件…

Kubectl命令、初识pod、namespace

文章目录 一、Kubectl简介基础命令1.基本信息命令2.创建和更新资源命令3.删除资源命令4. 查看日志和调试命令5. 端口转发和复制文件命令6. 部署管理命令7. 伸缩命令8. 配置和上下文管理命令9.常用命令 二、Pod简介核心概念pod常见状态调度和初始化阶段容器创建和运行阶段异常状…

Qt网络通信——TCP和UDP

一、TCP通信 TCP通信必须先建立 TCP 连接&#xff0c;通信端分为客户端和服务器端。 Qt 为服务器端提供了 QTcpServer 类用于实现端口监听&#xff0c;QTcpSocket 类则用于服务器和客户端之间建立连接。大致流程如下图所示&#xff1a; 1. 服务器端建立 1.1 监听——listen() …

PPP简介

介绍PPP特性的定义和目的。 定义 PPP&#xff08;Point-to-Point Protocol&#xff09;协议是一种点到点链路层协议&#xff0c;主要用于在全双工的同异步链路上进行点到点的数据传输。 目的 PPP协议是在串行线IP协议SLIP&#xff08;Serial Line Internet Protocol&#x…

代码随想录:动态规划6-10

62、不同路径 题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径…

史上最全的软件工厂考试简答题教程

软件工程考试简答题 1. 有人认为软件开发时&#xff0c;一个错误发现得越晚&#xff0c;为改正它所付出的代价越大。提出你的观点并解释原因&#xff1f; &#xff08;1&#xff09;在软件开发的不同阶段进行修改付出的代价是很不相同的&#xff0c;在早期引入变动&#xff0c…

openai whisper使用

whisper使用 介绍 Whisper是一种通用的语音识别模型。它是在大量不同音频数据集上训练的&#xff0c;也是一个多任务模型&#xff0c;可以执行多语言语音识别、语音翻译和语言识别。 GitHub&#xff1a;https://github.com/openai/whisper 论文链接&#xff1a;https://arx…

注册Github账号详细过程

目录 一、准备工作 二、注册步骤 一、准备工作 在注册GitHub账号之前&#xff0c;请确保您已经准备好以下信息&#xff1a; 一个有效的电子邮箱地址&#xff1a;用于接收验证邮件和GitHub的后续通知。 用户名&#xff1a;确保该用户名在GitHub上是唯一的&#xff0c;且符合…

turtle画图知识

Turtle库是Python编程语言中的一个库&#xff0c;用于创建各种类型的图形&#xff0c;包括简单圆形、线条、路径和图片。它支持多种图形类型&#xff0c;并且可以绘制出各种复杂的形状。 以下是一些基本的使用方法&#xff1a; 1. 创建一个新的Turtle对象&#xff1a; pytho…

Leetcode JAVA刷刷站(53)最大子数组和

一、题目概述 二、思路方向 这个问题是一个经典的算法问题&#xff0c;称为“最大子序和”&#xff08;Maximum Subarray Problem&#xff09;。解决这个问题的一个高效方法是使用“Kadanes Algorithm”&#xff0c;它只需要遍历数组一次&#xff0c;就能在 O(n) 时间复杂度内…

CVPR2023《DNF: Decouple and Feedback Network for Seeing in the Dark》暗光图像增强论文阅读笔记

相关链接 论文链接 https://openaccess.thecvf.com/content/CVPR2023/papers/Jin_DNF_Decouple_and_Feedback_Network_for_Seeing_in_the_Dark_CVPR_2023_paper.pdf 代码链接 https://github.com/Srameo/DNF 摘要 RAW数据的独特属性在低光照图像增强方面展现出巨大潜力。…

C语言典型例题47

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 习题3.7 输入4个整数&#xff0c;要求按照从小到大的顺序输出 4个数之间进行比较&#xff0c;冒泡排序最最最详细过程&#xff0c;如果想更改为任意数之间相互比较&#xff0c;只需要修改两个地方&#xff08;数组大…

力扣面试经典算法150题:买卖股票的最佳时机 II

买卖股票的最佳时机 II 今天的题目是力扣面试经典150题中的数组的中等难度题&#xff1a;买卖股票的最佳时机 II。 题目链接&#xff1a;https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/?envTypestudy-plan-v2&envIdtop-interview-150 问…