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

目录

引言

队列的定义

队列的分类

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方法使…

找到sql里面参数字段占位符的位置,方便对字段进行加密存储

CCJSqlParserUtil工具是强大&#xff0c;难用也是真的&#xff0c;得分析sql的各种各样的表达式。从中递归找出业务需要的。 public class SqlExpressionAnalyzer {public static void main(String[] args) {String sql "select id,user_name from sys_user t1,sys_offi…

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.如何去操作对象 修改属性…

Jenkins 定时触发策略

每天晚上 11 点执行一次&#xff0c;可以按照以下步骤进行。 复制代码 import jenkins import datetime import base64USERNAME bUFNXssaaX0NU\n PASSWORD bUFNXXssdds0Ndclass JenkinsMonitor:def __init__(self, jobs_to_monitor):self.jenkins_url "http://pe-dddd…

fastJSON工具类

1 总结 1&#xff1a; JSONObject&#xff1a; 理解为 Map 2&#xff1a;JSONArray &#xff1a; 理解为List<Map> 3&#xff1a;JSON.toJSONString()&#xff1b;会将时间转为时间戳 4&#xff1a;toJSONStringWithDateFormat 同一个字符串中 时间格式是统一格式 2 转成…

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

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

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

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

AND 运算符的优先级高于 OR

在 SQL 中&#xff0c;AND 运算符的优先级高于 OR。这意味着您的查询可能会不按预期执行。为了确保逻辑的正确性&#xff0c;您可能需要使用括号来明确指定运算符的优先级。 正确的&#xff1a;and后用括号把or括起来 SELECT * FROM student WHERE data_status 0 AND (name L…

python-docx 实现 Word 办公自动化

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

图像直方图比较

对于直方图的比较&#xff0c;我们可以使用 OpenCV 提供的函数 compareHist() 进行比较&#xff0c;从而得到一个数值&#xff0c;表示两个直方图的匹配程度&#xff08;相似性&#xff09;。 原理 对于两个直方图&#xff08; H 1 H_{1} H1​ 和 H 2 H_{2} H2​&#xff09…

【大数据】基础认知入门

目录 前言阅读对象阅读导航前置知识笔记正文一、什么是大数据1.1 定义1.2 特点1.3 数据结构1.4 补充总结 二、大数据能用来干什么2.1 应用方向2.2 应用场景&#xff08;简述&#xff09;2.3 总结 三、大数据一般性过程四、给自己的作业 感谢说在后面 前言 唉&#xff0c;最近有…

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…

【Android高级UI】将View或Layout裁剪为任意形状

需求 将View裁剪为指定形状 将Layout裁剪为指定形状&#xff0c;并且Children不能超过裁剪范围 应用 圆角图片异形图片圆角Layout 方案 通过ViewOutlineProvider裁剪控件范围 实现 fun View.getMeasureSize(): Size {val widthSpec View.MeasureSpec.makeMeasureSpec(…

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

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

Hadoop入门基础(三):Hadoop启动踩坑记录

一、机器ssh连接方式非默认22端口 报错&#xff1a; sbin/start-dfs.sh Starting namenodes on [doop253] doop253: ssh: connect to host doop253 port 22: Connection refused 解决方法&#xff1a; sudo vim /etc/ssh/ssh_config 添加如下内容&#xff08;注意替换自己服…