栈和队列(C语言)

栈的定义

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶
可以把他想象成一个水杯

栈代码的实现

结构的定义,以及函数声明

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int QueueNodeType;
struct QueueNode {struct QueueNode* next;QueueNodeType data;
}typedef QueueNode;//队列只需要在队尾插入,队头删除,不需要改变里面的内容
//所以只需要改变头尾
struct Queue {struct QueueNode* head;struct QueueNode* tail;size_t _size;
}typedef Queue;// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QueueNodeType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QueueNodeType QueueFront(Queue* q);
// 获取队列队尾元素
QueueNodeType QueueBack(Queue* q);
// 获取队列中有效元素个数
size_t QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);

接口的实现

#define  _CRT_SECURE_NO_WARNINGS 1
#include "queue.h"void QueueInit(Queue* q)
{assert(q);q->head = NULL;q->tail = NULL;q->_size = 0;
}void QueueDestroy(Queue* q)
{assert(q);while (q->head){QueueNode* next = q->head->next;free(q->head);q->head = next;}q->tail = NULL;q->_size = 0;
}void QueuePush(Queue* q, QueueNodeType data)
{assert(q);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));assert(newnode);newnode->data = data;newnode->next = NULL;//尾插if (q->tail == NULL){q->tail = q->head = newnode;}else{q->tail->next = newnode;q->tail = q->tail->next;}q->_size++;
}void QueuePop(Queue* q)
{assert(q);assert(!QueueEmpty(q));QueueNode* newhead = q->head->next;free(q->head);q->head = newhead;if (q->head == NULL){q->tail = NULL;}q->_size--;
}bool QueueEmpty(Queue* q)
{assert(q);return q->head == NULL;
}QueueNodeType QueueFront(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->head->data;
}QueueNodeType QueueBack(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->tail->data;
}size_t QueueSize(Queue* q)
{assert(q);return q->_size;
}

队列的定义

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头

队列代码的实现

结构的定义,以及函数声明

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int QueueNodeType;
struct QueueNode {struct QueueNode* next;QueueNodeType data;
}typedef QueueNode;//队列只需要在队尾插入,队头删除,不需要改变里面的内容
//所以只需要改变头尾
struct Queue {struct QueueNode* head;struct QueueNode* tail;size_t _size;
}typedef Queue;// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QueueNodeType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QueueNodeType QueueFront(Queue* q);
// 获取队列队尾元素
QueueNodeType QueueBack(Queue* q);
// 获取队列中有效元素个数
size_t QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);

接口的实现

#define  _CRT_SECURE_NO_WARNINGS 1
#include "queue.h"void QueueInit(Queue* q)
{assert(q);q->head = NULL;q->tail = NULL;q->_size = 0;
}void QueueDestroy(Queue* q)
{assert(q);while (q->head){QueueNode* next = q->head->next;free(q->head);q->head = next;}q->tail = NULL;q->_size = 0;
}void QueuePush(Queue* q, QueueNodeType data)
{assert(q);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));assert(newnode);newnode->data = data;newnode->next = NULL;//尾插if (q->tail == NULL){q->tail = q->head = newnode;}else{q->tail->next = newnode;q->tail = q->tail->next;}q->_size++;
}void QueuePop(Queue* q)
{assert(q);assert(!QueueEmpty(q));QueueNode* newhead = q->head->next;free(q->head);q->head = newhead;if (q->head == NULL){q->tail = NULL;}q->_size--;
}bool QueueEmpty(Queue* q)
{assert(q);return q->head == NULL;
}QueueNodeType QueueFront(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->head->data;
}QueueNodeType QueueBack(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->tail->data;
}size_t QueueSize(Queue* q)
{assert(q);return q->_size;
}

题目1:括号匹配问题

题目链接:https://leetcode.cn/problems/valid-parentheses/description/
在这里插入图片描述
思路详解:
在这里插入图片描述

参考代码

typedef char StackType;struct Stack {StackType* _a;int _top;int _capacity;
}typedef Stack;//初始化栈
void StackInit(Stack* pStack);//入栈
void StackPush(Stack* pStack,StackType data);//出栈
void StackPop(Stack* pStack);//获取栈顶元素
StackType StackTop(const Stack* pStack);//获取栈中有效元素个数
int StackSize(const Stack* pStack);//判断栈是否为空
bool StackEmpty(Stack* pStack);//销毁栈
void StackDestroy(Stack* pStack);void StackInit(Stack* pStack)
{pStack->_a = NULL;pStack->_capacity = 0;pStack->_top = 0;
}void StackPush(Stack* pStack,StackType data)
{assert(pStack);if (pStack->_top == pStack->_capacity){int newCapacity = pStack->_capacity == 0 ? 4 : pStack->_capacity * 2;StackType* newa = NULL;newa = (StackType*)realloc(pStack->_a, sizeof(StackType) * newCapacity);if (newa == NULL){perror("StackPush():: realloc::");return;}pStack->_a = newa;pStack->_capacity = newCapacity;}pStack->_a[pStack->_top] = data;pStack->_top++;
}void StackPop(Stack* pStack)
{assert(pStack);assert(!StackEmpty(pStack));pStack->_top--;
}StackType StackTop(const Stack* pStack)
{// 因为top的初始值为0 ,而插入一个数据后为1,// 但是所对应的数组下标为0assert(pStack);assert(!StackEmpty(pStack));return pStack->_a[pStack->_top - 1];
}int StackSize(const Stack* pStack)
{return pStack->_top;
}bool StackEmpty(Stack* pStack)
{assert(pStack);return pStack->_top == 0;
}void StackDestroy(Stack* pStack)
{free(pStack->_a);pStack->_capacity = 0;pStack->_top = 0;pStack->_a = NULL;
}
//这里题目实现,上面都是栈的实现和接口,因为是C语言的关系没有STL库所以要自己造轮子
bool isValid(char* s) 
{Stack stack = { 0 };StackInit(&stack);while (*s){if (*s == '(' || *s == '{' || *s == '['){StackPush(&stack, *s);s++;}else{//第一个字符为有括号,证明不是有效括号,直接返回NULLif(StackEmpty(&stack)){//特殊案例如果是 [[]]],这里如果直接返回的话就会导致内存泄露StackDestroy(&stack);return false;}StackType top = StackTop(&stack);StackPop(&stack);if (top == '(' && *s != ')'|| top == '{' && *s != '}'|| top == '[' && *s != ']'){StackDestroy(&stack);return false;}else{ s++;}}}bool ret = StackEmpty(&stack);StackDestroy(&stack);return ret;// return true;
}

题目2:用队列实现栈

题目链接:https://leetcode.cn/problems/implement-stack-using-queues/
在这里插入图片描述
思路详解:
在这里插入图片描述
在这里插入图片描述

参考代码:

typedef int QueueNodeType;
struct QueueNode {struct QueueNode* next;QueueNodeType data;
}typedef QueueNode;//队列只需要在队尾插入,队头删除,不需要改变里面的内容
//所以只需要改变头尾
struct Queue {struct QueueNode* head;struct QueueNode* tail;size_t _size;
}typedef Queue;// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QueueNodeType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QueueNodeType QueueFront(Queue* q);
// 获取队列队尾元素
QueueNodeType QueueBack(Queue* q);
// 获取队列中有效元素个数
size_t QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);void QueueInit(Queue* q)
{assert(q);q->head = NULL;q->tail = NULL;q->_size = 0;
}void QueueDestroy(Queue* q)
{assert(q);while (q->head){QueueNode* next = q->head->next;free(q->head);q->head = next;}q->tail = NULL;q->_size = 0;
}void QueuePush(Queue* q, QueueNodeType data)
{assert(q);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));assert(newnode);newnode->data = data;newnode->next = NULL;//尾插if (q->tail == NULL){q->tail = q->head = newnode;}else{q->tail->next = newnode;q->tail = q->tail->next;}q->_size++;
}void QueuePop(Queue* q)
{assert(q);assert(!QueueEmpty(q));QueueNode* newhead = q->head->next;free(q->head);q->head = newhead;if (q->head == NULL){q->tail = NULL;}q->_size--;
}bool QueueEmpty(Queue* q)
{assert(q);return q->head == NULL;
}QueueNodeType QueueFront(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->head->data;
}QueueNodeType QueueBack(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->tail->data;
}size_t QueueSize(Queue* q)
{assert(q);return q->_size;
}//上面是队列的接口,从这里下面才开始对栈的实现
typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack* mystack = (MyStack*)malloc(sizeof(MyStack));QueueInit(&mystack->q1);QueueInit(&mystack->q2);return mystack;
}void myStackPush(MyStack* obj, int x) {if(QueueEmpty(&obj->q1)){QueuePush(&obj->q2,x);}else{QueuePush(&obj->q1,x);}
}int myStackPop(MyStack* obj) {//找那个是为空队列Queue* emptyQueue = &obj->q1;Queue* nonEmptyQueue = &obj->q2;if(QueueEmpty(&obj->q2)){emptyQueue = &obj->q2;nonEmptyQueue = &obj->q1;}//保留非空队列中的最后一个元素,其余元素转移到空队列里面while(QueueSize(nonEmptyQueue) > 1){QueuePush(emptyQueue,QueueFront(nonEmptyQueue));QueuePop(nonEmptyQueue);}int ret = QueueFront(nonEmptyQueue);QueuePop(nonEmptyQueue);return ret;
}int myStackTop(MyStack* obj) {//两个队列中,非空的那个队列的队尾就是栈顶if(QueueEmpty(&obj->q1)){return QueueBack(&obj->q2); }else{return QueueBack(&obj->q1);}
}bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);
}

题目3:用栈实现队列

题目链接:https://leetcode.cn/problems/implement-queue-using-stacks/description/

在这里插入图片描述
思路详解:
在这里插入图片描述

参考代码:

typedef char StackType;struct Stack {StackType* _a;int _top;int _capacity;
}typedef Stack;//初始化栈
void StackInit(Stack* pStack);//入栈
void StackPush(Stack* pStack,StackType data);//出栈
void StackPop(Stack* pStack);//获取栈顶元素
StackType StackTop(Stack* pStack);//获取栈底元素
StackType StackBottom(Stack* pStack);//获取栈中有效元素个数
int StackSize(Stack* pStack);//判断栈是否为空
bool StackEmpty(Stack* pStack);//销毁栈
void StackDestroy(Stack* pStack);void StackInit(Stack* pStack)
{pStack->_a = NULL;pStack->_capacity = 0;pStack->_top = 0;
}void StackPush(Stack* pStack,StackType data)
{assert(pStack);if (pStack->_top == pStack->_capacity){int newCapacity = pStack->_capacity == 0 ? 4 : pStack->_capacity * 2;StackType* newa = NULL;newa = (StackType*)realloc(pStack->_a, sizeof(StackType) * newCapacity);if (newa == NULL){perror("StackPush():: realloc::");return;}pStack->_a = newa;pStack->_capacity = newCapacity;}pStack->_a[pStack->_top] = data;pStack->_top++;
}void StackPop(Stack* pStack)
{assert(pStack);assert(!StackEmpty(pStack));pStack->_top--;
}StackType StackTop(Stack* pStack)
{assert(pStack);assert(!StackEmpty(pStack));// 因为top的初始值为0 ,而插入一个数据后为1,// 但是所对应的数组下标为0return pStack->_a[pStack->_top - 1];
}StackType StackBottom(Stack* pStack)
{assert(pStack);assert(!StackEmpty(pStack));return pStack->_a[0];
}int StackSize(Stack* pStack)
{return pStack->_top;
}bool StackEmpty(Stack* pStack)
{assert(pStack);return pStack->_top == 0;
}void StackDestroy(Stack* pStack)
{free(pStack->_a);pStack->_capacity = 0;pStack->_top = 0;pStack->_a = NULL;
}//这里开始才是实现队列的代码
typedef struct {Stack PushStack;Stack PopStack;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* queue= (MyQueue*)malloc(sizeof(MyQueue));StackInit(&queue->PushStack);StackInit(&queue->PopStack);return queue;
}void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->PushStack,x);
}int myQueuePop(MyQueue* obj) {if(StackEmpty(&obj->PopStack)){while(!StackEmpty(&obj->PushStack)){StackPush(&obj->PopStack,StackTop(&obj->PushStack));StackPop(&obj->PushStack);}}int popTop = StackTop(&obj->PopStack);StackPop(&obj->PopStack);return popTop;
}//返回队头
int myQueuePeek(MyQueue* obj) {if(StackEmpty(&obj->PopStack)){while(!StackEmpty(&obj->PushStack)){StackPush(&obj->PopStack,StackTop(&obj->PushStack));StackPop(&obj->PushStack);}}return StackTop(&obj->PopStack);
}bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->PushStack) && StackEmpty(&obj->PopStack);
}void myQueueFree(MyQueue* obj) {StackDestroy(&obj->PopStack);StackDestroy(&obj->PushStack);free(obj);
}

题目4:设计循环队列

题目链接:https://leetcode.cn/problems/design-circular-queue/description/
在这里插入图片描述
思路详解:

在这里插入图片描述

参考代码:
用数组实现:

typedef struct {int* _a; //数组int _head; //头下标int _tail; //尾下标int _k; //存储的元素个数
} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);// 初始化
MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));assert(cq);cq->_a = (int*)malloc(sizeof(int) * (k + 1));assert(cq->_a);cq->_head = 0;cq->_tail = 0;cq->_k = k;return cq;
}// 入队列
bool myCircularQueueEnQueue(MyCircularQueue * obj, int value) {assert(obj);if (myCircularQueueIsFull(obj)){return false;}else{obj->_a[obj->_tail] = value;if (obj->_tail >= obj->_k){obj->_tail = 0;}else{obj->_tail++;}return true;}
}//删队列
bool myCircularQueueDeQueue(MyCircularQueue* obj) {assert(obj);if (myCircularQueueIsEmpty(obj)){return false;}if (obj->_head >= obj->_k){obj->_head = 0;return true;}else{obj->_head++;return true;}
}//队头
int myCircularQueueFront(MyCircularQueue* obj) {assert(obj);if (myCircularQueueIsEmpty(obj)){return -1; }return obj->_a[obj->_head];
}//队尾
int myCircularQueueRear(MyCircularQueue* obj) {assert(obj);if (myCircularQueueIsEmpty(obj)){return -1;}//方法1;if (obj->_tail == 0){return obj->_a[obj->_k];}else{return obj->_a[obj->_tail - 1];}//方法2:/*int i = (obj->_tail + obj->_k) % (obj->_k + 1);return obj->_a[i];*/
}//判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {assert(obj);return obj->_head == obj->_tail;
}//判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {assert(obj);return (obj->_tail + 1) % (obj->_k + 1) == obj->_head;
}//销毁
void myCircularQueueFree(MyCircularQueue* obj) {assert(obj);free(obj->_a);free(obj);
}

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

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

相关文章

20分钟上手新版Skywalking 9.x APM监控系统

Skywalking https://skywalking.apache.org/ Skywalking是专为微服务、云原生和基于容器的&#xff08;Kubernetes&#xff09;架构设计的分布式系统性能监控工具。 Skywalking关键特性 ● 分布式跟踪 ○ 端到端分布式跟踪。服务拓扑分析、以服务为中心的可观察性和API仪表板。…

【stm32项目】基于stm32智能宠物喂养(完整工程资料源码)

基于STM32宠物喂养系统 前言&#xff1a; 随着人们生活幸福指数的提高&#xff0c;越来越多的家庭选择养宠物来为生活增添乐趣。然而&#xff0c;由于工作等原因&#xff0c;许多主人无法及时为宠物提供充足的食物与水。为了解决这一问题&#xff0c;我设计了一款便捷的宠物喂…

linux C++ onnxruntime yolov8 视频检测Demo

linux C onnxruntime yolov8 视频检测Demo 目录 项目目录 效果 ​编辑CMakeLists.txt 代码 下载 项目目录 效果 ./yolov8_demo --help ./yolov8_demo -c2 -ptrue ./yolov8_demo -c1 -strue CMakeLists.txt # cmake needs this line cmake_minimum_required(VERSION 3…

vim gcc

vim 使用 vs filename 分屏 ctrl ww 切窗口 shift zz 快速提出vim vim配置 vim启动时自动读取当前用户的家目录的.vimrc文件 vim配置只影响本用户 其他用户观看同一文件不受影响 gcc指令 & c文件编译过程 动态库 静态库 & 链接方式 有相应库才能进行…

【机器学习】不同操作系统下如何安装Jupyter Notebook和Anaconda

引言 Jupyter Notebook 是一个非常流行的开源Web应用程序&#xff0c;允许你创建和共享包含代码、方程、可视化和解释性文本的文档 文章目录 引言一、如何安装Jupyter Notebook1.1 对于Windows用户1.2 对于macOS用户1.3 对于Linux用户&#xff1a; 二、如何安装Anaconda2.1 对于…

css气泡背景特效

css气泡背景特效https://www.bootstrapmb.com/item/14879 要创建一个CSS气泡背景特效&#xff0c;你可以使用CSS的伪元素&#xff08;:before 和 :after&#xff09;、border-radius 属性来创建圆形或椭圆形的“气泡”&#xff0c;以及background 和 animation 属性来设置背景…

基于 Electron+Vite+Vue3+Sass 框架搭建

技术参考 技术描述Electron一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。嵌入 Chromium 和 Node.jsElectron Forge用于打包和分发 Electron 应用程序的一体化工具。英文地址在此Vite前端构建工具Vue3用于构建用户界面的 JavaScript 框架vitejs/plugin-vueVite 插…

java基础-String

之前有很长时间没进行更新了&#xff0c;现在开始会重新进行java基础的学习&#xff0c;所以会开始进行java基础方面的更新&#xff0c;今天会进行string字符串的学习。 String在底层被final(声明的变量或者对象不可以扩展/改变)修饰&#xff0c;故其不可变。其底层采用的是字符…

springboot集成redis之字典缓存

什么是redis的字典缓存&#xff1f; Redis的缓存是Redis内部用于存储键值对数据结构的一种基础数据结构。在Redis中&#xff0c;所有的键值对都是通过字典这种数据结构来存储的。字典在Redis中扮演着核心角色&#xff0c;因为它不仅用于数据库中的键值对存储&#xff0c;还用于…

Postman设置全部请求都携带请求头,Postman如何一次性设置请求头、不需要一个请求一个请求去添加请求头

文章目录 一、问题描述二、解决办法三、应用场景 一、问题描述 现在我有 n 个接口测试&#xff0c;其中 n 个都需要携带一致的请求头&#xff08;其实一般都是携带 JWT 令牌&#xff09;&#xff0c;怎么办&#xff1f;我要一个一个写&#xff1f;如图&#xff1a; 二、解决办…

go语言Gin框架的学习路线(十)

目录 GORM的CRUD教程 查询 普通查询 定义 User 结构体 查询所有用户 查询第一个用户 总结 条件查询 内联条件 额外查询选项 高级查询 链式操作 Scopes 多个立即执行方法 GORM的CRUD教程 CRUD 是 "Create, Read, Update, Delete"&#xff08;创建、查询…

[经验] 驰这个汉字的拼音是什么 #学习方法#其他#媒体

驰这个汉字的拼音是什么 驰&#xff0c;是一个常见的汉字&#xff0c;其拼音为“ch”&#xff0c;音调为第四声。它既可以表示动词&#xff0c;也可以表示形容词或副词&#xff0c;意义广泛&#xff0c;经常出现在生活和工作中。下面就让我们一起来了解一下“驰”的含义和用法。…

以Zookeeper为例 浅谈脑裂与奇数节点问题

一、脑裂现象的定义与影响 脑裂&#xff08;split-brain&#xff09;是指在分布式系统中&#xff0c;因网络分区或其他故障导致系统被切割成两个或多个相互独立的子系统&#xff0c;每个子系统可能独立选举出自己的领导节点。这一现象在依赖中心领导节点&#xff08;如Elastic…

【Qt 】JSON 数据格式详解

文章目录 1. JSON 有什么作用?2. JSON 的特点3. JSON 的两种数据格式3.1 JSON 数组3.2 JSON 对象 4. Qt 中如何使用 JSON 呢&#xff1f;4.1 QJsonObject4.2 QJsonArray4.3 QJsonValue4.4 QJsonDocument 5. 构建 JSON 字符串6. 解析 JSON 字符串 1. JSON 有什么作用? &#x…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第三十九章 Linux MISC驱动

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

5.Fabric的共识机制

在Fabric中,有以下3中典型共识机制。 Solo共识 solo共识机制只能用于单节点模式,即只能有一个Orderer节点,因此,其共识过程很简单,每接收到一个交易信息,就在共识模块的控制下产生区块并广播给节点存储到账本中。 Solo 模式下的共识只适用于一个Orderer节点,所以可以在…

CTF-Web习题:2019强网杯 UPLOAD

题目链接&#xff1a;2019强网杯 UPLOAD 解题思路 打开靶场如下图所示&#xff0c;是一个注册和登录界面 那就注册登录一下&#xff0c;发现是一个提交头像的页面&#xff1a; 试了一下只有能正确显示的png图片才能提交成功&#xff0c;同时F12拿到cookie&#xff0c;base6…

便宜多域名SSL证书申请平台推荐

随着互联网的深入发展&#xff0c;网络安全问题愈发受到重视。SSL证书作为保障网站和用户数据安全的重要工具&#xff0c;其重要性不言而喻。在众多SSL证书类型中&#xff0c;多域名SSL证书因其独特的功能和优势&#xff0c;逐渐成为企业和个人保护网站安全的首选。 申请便宜S…

Django视图与URLs路由详解

在Django Web框架中&#xff0c;视图&#xff08;Views&#xff09;和URLs路由&#xff08;URL routing&#xff09;是Web应用开发的核心概念。它们共同负责将用户的请求映射到相应的Python函数&#xff0c;并返回适当的响应。本篇博客将深入探讨Django的视图和URLs路由系统&am…

全国区块链职业技能大赛国赛考题区块链产品需求分析与方案设计

任务1-1:区块链产品需求分析与方案设计 本任务需要依据项目背景完成需求分析与方案设计,具体要求如下: 依据给定区块链食品溯源系统的业务架构图,对考题进行业务分析,尽可能多的去考虑一个业务系统所需要的模块,使用Visio或思维导图工具展现本系统的基本设计概念和处理流…