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

单链表的详解实现

单链表

结构

单链表结构中有两个数据,一个是存储数据的,还有一个指针指向下一个节点。

在这里插入图片描述
该图就是一个简单单链表的结构图。

接口实现

SLNode* CreateNode(SLNDataType x);//申请节点
void SLTprint(SLNode* head);//打印链表
void SLTPushBack(SLNode** pphead, SLNDataType x);//尾插
void SLTPushFront(SLNode** pphead, SLNDataType x);//头插
void SLTPopBack(SLNode** pphead);//尾删
void SLTPopFront(SLNode** pphead);//头删
SLNode* SLTFind(SLNode* phead, SLNDataType x);//查找
SLNode* SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x);//任意位置插入
void SLTErase(SLNode** pphead, SLNode* pos);//任意位置删除
void SLTDestroy(SLNode** pphead);//销毁链表

结构体的定义

typedef int SLNDataType;
typedef struct SListNode
{SLNDataType val;struct SList* next;
}SLNode;

首先,我们需要定义这样一个结构体,用来实现链表。本章禁用数字来实现,想用链表写一些学生信息的朋友们可以参考一下。

申请节点

SLNode* CreateNode(SLNDataType x)
{SLNode* newnode=(SLNode*)malloc(sizeof(SLNode));//动态申请内存SLNode大小即可,存放到SLNode* 的指针中去if (newnode == NULL)//如果申请失败,则提醒一下{perror("malloc fail");exit("-1");}newnode->val = x;//申请成功后,将该数据存放到该指针指向的val中去newnode->next = NULL;//将下一个节点设置为空指针return newnode;//返回值为该节点
}

首先,我们插入一个数据的时候,必须要开辟一个空间,也就是申请一个节点用来存放数据,所以单独封装这个函数来实现这个功能。

链表的打印

void SLTprint(SLNode* head)
{assert(head);//断言保证传入指针非空SLNode* cur = head;while (cur!=NULL)//打印循环{printf("%d->", cur->val);//打印当前指针指向的val值cur = cur->next;//将该指针指向的下一个指针的地址赋给该指针,实现链表的遍历}printf("NULL\n");
}

我们接受该指针,之后检查是否为空,把该指针重新赋给一个SLNode* 类型的cur进入打印循环,循环结束条件为尾指针指向的指针不为空指针即可。

尾插

我们插入删除数据时候,需要注意的一点是,我们需要遍历修改的时一级指针,那么我们就要用二级指针去接受这个参数了。

void SLTPushBack(SLNode** pphead, SLNDataType x)
{assert(pphead);//断言非空SLNode* newnode = CreateNode(x);//将新开辟的节点赋给newnodeif (*pphead == NULL)//链表为空{*pphead = newnode;//直接将newnode赋给头节点}else{SLNode* tmp = *pphead;//将头节点给一个临时变量while (tmp->next != NULL)//遍历循环{tmp = tmp->next;//可实现链表移动从而遍历}tmp->next = newnode;//让最后一个节点指向newnode即可}
}

我们实现尾部插入,有两种情况,首先就是如果该链表为空,也就是头节点指向的是空指针,那么我们直接将新开辟的节点赋给头节点即可,其他的情况,首先需要遍历链表到最后一个节点,然后让最后一个节点指向新开辟的节点即可实现尾部插入。

头插

void SLTPushFront(SLNode** pphead, SLNDataType x)
{assert(pphead);//断言非空SLNode* newnode = CreateNode(x);//将新开辟的节点赋给newnode节点newnode->next = *pphead;//新开辟的节点指向的是pphead节点*pphead = newnode;//newnode成为新的头节点
}

实现头插是十分简单的,直接看代码注释即可

尾删

void SLTPopBack(SLNode** pphead)
{assert(*pphead);//保证头节点不为空指针if ((*pphead)->next == NULL)//仅有一个节点的情况{free(*pphead);//释放掉头节点*pphead = NULL;//并将其赋值为空指针即可}else//多个节点的情况{SLNode* prev = NULL;//双指针移动之实际指针SLNode* tail = *pphead;//双指针移动之遍历指针while (tail->next!= NULL)//遍历循环,结束条件为tail的下一个节点不为空指针{prev = tail;//将遍历指针赋值给实际指针tail = tail->next;//遍历指针向后移动}
//循环结束,此时实际指针指向倒数第二个节点,而遍历指针指向最后一个节点free(tail);//释放掉此时指向最后一个节点的遍历节点tail = NULL;//将释放后的遍历指针赋值为空指针prev->next = NULL;//实际指针变成最后一个指针,最后一个指针指向的是空指针}
}

尾删,我们需要分为两种情况,首先是该链表只有一个头节点,这种情况直接将头节点释放掉在赋值为空指针即可,另外的就是该链表有多个节点,那么此时我们选哟做到的就是,遍历到最后一个节点,之后将该节点释放掉即可,这里我们用双指针的移动来实现释放节点。

头删

void SLTPopFront(SLNode** pphead)
{assert(*pphead);//保证头节点不为空SLNode* tmp = *pphead;//将头节点赋给临时节点(*pphead) = tmp->next;//临时节点也就是头节点指向的下一个节点赋给头节点成为新的头节点free(tmp);//释放掉已经不是头节点的节点tmp = NULL;//将释放掉的节点赋值为空指针
}

头删十分简单,直接看代码注释即可。

查找

SLNode* SLTFind(SLNode* phead, SLNDataType x)
{if (phead == NULL)//头节点为空指针,也就是链表为空无需打印{printf("链表为空无需查找");return NULL;//返回空指针}else//链表不为空{SLNode* cur = phead;//将头节点赋给临时变量curwhile (cur)//遍历循环{if (cur->val== x)//如果遍历的数据是所需要的数据{return cur;//返沪该指针}cur = cur->next;//如果不是,则移动临时变量cur实现链表的遍历}}return NULL;//找完没有,则返回空指针
}

查找的实现也很简单,如果链表为空,那么我们就无需查找,返回空指针即可,不为空,我们遍历找到需要数据存放的节点,之后返回这个节点就可以了,如果遍历完没有找到,就说明不存在该节点返回空指针即可。

任意位置的插入

SLNode* SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{assert(pphead);//断言非空if (*pphead == pos)//头插情况{SLTPushFront(pphead,x);}else//非头部插入情况{SLNode* newnode = CreateNode(x);//新开辟的节点赋给newnode指针SLNode* cur = *pphead;//头节点给临时变量curwhile (cur->next != pos)//遍历到pos前一个位置{cur = cur->next;//遍历移动}cur->next = newnode;//此时让pos位置前一个节点指向要插入的节点newnode->next = pos;//要插入的节点指向之后的节点,实现链表的完整}
}

首先,如果插入的位置是头节点,那么也就是头插了,如果是其他位置,那么首先需要遍历到该位置的前一个节点,让该节点指向新插入的节点,新插入的节点在指向原来该位置的节点就实现了该位置的数据插入。

任意位置的删除

void SLTErase(SLNode** pphead, SLNode* pos)
{assert(pphead);//断言非空if (*pphead == pos)//头删情况{SLTPopFront(pphead);}else//非头删情况{SLNode* cur = *pphead;//头节点赋给临时变量curwhile (cur->next != pos)//遍历到pos位置的前一个节点循环{cur = cur->next;//临时变量移动,链表的遍历}cur->next = pos->next;//pos位置的前一个节点直线pos的下一个节点free(pos);//释放pospos = NULL;//pos赋值为空指针}
}

首先,也是如果删除的节点是头节点,直接头删即可,不是则遍历到该位置的前一个位置,跳过该位置指向下一个节点,再将该位置节点释放掉即可。

链表的销毁

void SLTDestroy(SLNode** pphead)
{assert(pphead);SLNode* cur = *pphead;while (cur){SLNode* pur = cur;cur = cur->next;free(pur);}printf("链表已经成功销毁!");
}

链表的销毁十分简单,遍历释放即可。

代码参考

鄙人不才,大家可以参考一下链表代码的实现

SList.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>typedef int SLNDataType;
typedef struct SListNode
{SLNDataType val;struct SList* next;
}SLNode;
SLNode* CreateNode(SLNDataType x);//申请节点
void SLTprint(SLNode* head);//打印链表
void SLTPushBack(SLNode** pphead, SLNDataType x);//尾插
void SLTPushFront(SLNode** pphead, SLNDataType x);//头插
void SLTPopBack(SLNode** pphead);//尾删
void SLTPopFront(SLNode** pphead);//头删
SLNode* SLTFind(SLNode* phead, SLNDataType x);//查找
SLNode* SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x);//任意位置插入
void SLTErase(SLNode** pphead, SLNode* pos);//任意位置删除
void SLTDestroy(SLNode** pphead);//销毁链表

SList.c

#define  _CRT_SECURE_NO_WARNINGS
#include"SList.h"
SLNode* CreateNode(SLNDataType x)
{SLNode* newnode=(SLNode*)malloc(sizeof(SLNode));if (newnode == NULL){perror("malloc fail");exit("-1");}newnode->val = x;newnode->next = NULL;return newnode;
}
void SLTprint(SLNode* head)
{assert(head);SLNode* cur = head;while (cur!=NULL){printf("%d->", cur->val);cur = cur->next;}printf("NULL\n");
}
void SLTPushBack(SLNode** pphead, SLNDataType x)
{SLNode* newnode = CreateNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLNode* tmp = *pphead;while (tmp->next != NULL){tmp = tmp->next;}tmp->next = newnode;}
}
void SLTPushFront(SLNode** pphead, SLNDataType x)
{SLNode* newnode = CreateNode(x);newnode->next = *pphead;*pphead = newnode;
}
void SLTPopBack(SLNode** pphead)
{assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLNode* prev = NULL;SLNode* tail = *pphead;while (tail->next!= NULL){prev = tail;tail = tail->next;}free(tail);tail = NULL;prev->next = NULL;}
}
void SLTPopFront(SLNode** pphead)
{assert(*pphead);SLNode* tmp = *pphead;(*pphead) = tmp->next;free(tmp);tmp = NULL;
}
SLNode* SLTFind(SLNode* phead, SLNDataType x)
{if (phead == NULL){printf("链表为空无需查找");return NULL;}else{SLNode* cur = phead;while (cur){if (cur->val== x){return cur;}cur = cur->next;}}return NULL;
}
SLNode* SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{assert(pphead);if (*pphead == pos){SLTPushFront(pphead,x);}else{SLNode* newnode = CreateNode(x);SLNode* cur = *pphead;while (cur->next != pos){cur = cur->next;}cur->next = newnode;newnode->next = pos;}
}
void SLTErase(SLNode** pphead, SLNode* pos)
{assert(pphead);if (*pphead == pos){SLTPopFront(pphead);}else{SLNode* cur = *pphead;while (cur->next != pos){cur = cur->next;}cur->next = pos->next;free(pos);pos = NULL;}
}
void SLTDestroy(SLNode** pphead)
{assert(pphead);SLNode* cur = *pphead;while (cur){SLNode* pur = cur;cur = cur->next;free(pur);}printf("链表已经成功销毁!");
}

test.c

这个文件主要是为了检测链表代码是否有误,用于调试链表。

#define  _CRT_SECURE_NO_WARNINGS
#include"SList.h"
void test1()
{SLNode* S1=NULL;SLTPushBack(&S1, 1);SLTPushBack(&S1, 2);SLTPushBack(&S1, 3);SLTPushBack(&S1, 4);SLTprint(S1);
}
void test2()
{SLNode* S1 = NULL;SLTPushBack(&S1, 1);SLTPushBack(&S1, 2);SLTPushBack(&S1, 3);SLTPushBack(&S1, 4);SLTPushFront(&S1, 4);SLTprint(S1);
}
void test3()
{SLNode* S1 = NULL;SLTPushBack(&S1, 1);SLTPushBack(&S1, 2);SLTPushBack(&S1, 3);SLTPushBack(&S1, 4);SLTPushFront(&S1, 4);SLTPopBack(&S1);SLTprint(S1);
}
void test4()
{SLNode* S1 = NULL;SLTPushBack(&S1, 1);SLTPushBack(&S1, 2);SLTPushBack(&S1, 3);SLTPushBack(&S1, 4);SLTPushFront(&S1, 4);SLTPopBack(&S1);SLTPopFront(&S1);SLTprint(S1);
}
void test5()
{SLNode* S1 = NULL;SLTPushBack(&S1, 1);SLTPushBack(&S1, 2);SLTPushBack(&S1, 3);SLTPushBack(&S1, 4);SLTPushFront(&S1, 5);SLNode* x =SLTFind(S1,3);SLTprint(S1);printf("%d", x->val);}
void test6()
{SLNode* S1 = NULL;SLTPushBack(&S1, 1);SLTPushBack(&S1, 2);SLTPushBack(&S1, 3);SLTPushBack(&S1, 4);SLTPushFront(&S1, 4);SLTInsert(&S1, S1, 5);SLNode* S2 = S1->next;SLTInsert(&S1, S2, 8);SLTprint(S1);
}
void test7()
{SLNode* S1 = NULL;SLTPushBack(&S1, 1);SLTPushBack(&S1, 2);SLTPushBack(&S1, 3);SLTPushBack(&S1, 4);SLTPushFront(&S1, 4);SLTInsert(&S1, S1, 5);SLNode* S2 = S1->next;SLTInsert(&S1, S2, 8);SLTErase(&S1, S1);SLTErase(&S1, S2);SLTprint(S1);
}
void test8()
{SLNode* S1 = NULL;SLTPushBack(&S1, 1);SLTPushBack(&S1, 2);SLTPushBack(&S1, 3);SLTPushBack(&S1, 4);SLTPushFront(&S1, 4);SLTInsert(&S1, S1, 5);SLNode* S2 = S1->next;SLTInsert(&S1, S2, 8);SLTErase(&S1, S1);SLTErase(&S1, S2);SLTprint(S1);SLTDestroy(&S1);
}
int main()
{/*test1();*//*test2();*//*test3();*//*test4();*//*test5();*//*test6();*//*test7();*/test8();return 0;
}

最后谢谢大家观看,以后会奉上更多内容,大家共同进步!

相关文章:

单链表的详解实现

单链表 结构 单链表结构中有两个数据&#xff0c;一个是存储数据的&#xff0c;还有一个指针指向下一个节点。 该图就是一个简单单链表的结构图。 接口实现 SLNode* CreateNode(SLNDataType x);//申请节点 void SLTprint(SLNode* head);//打印链表 void SLTPushBack(SLNode*…...

抛弃 scp 改用 rsync,让 Linux 下文件传输高效无比

我们都使用过 scp 来传输文件。当传输在中途或甚至在 99% 时被中断时&#xff0c;&#xff08;每当我想起99%的中断传输时&#xff0c;我的心都很痛&#xff09;&#xff1b;让我们看看如何使用 rsync 来替代 scp&#xff0c;避免这样的不幸。 什么是rsync&#xff1f; Rsync…...

Leetcode 2919. Minimum Increment Operations to Make Array Beautiful

Leetcode 2919. Minimum Increment Operations to Make Array Beautiful 1. 解题思路2. 代码实现 题目链接&#xff1a;2919. Minimum Increment Operations to Make Array Beautiful 1. 解题思路 这一题就是一个动态规划的题目。 思路上来说&#xff0c;就是考察每一个没到…...

关键词搜索亚马逊商品数据接口(标题|主图|SKU|价格|优惠价|掌柜昵称|店铺链接|店铺所在地)

亚马逊提供了API接口来获取商品数据。其中&#xff0c;关键词搜索亚马逊商品接口&#xff08;item_search-按关键字搜索亚马逊商品接口&#xff09;可以用于获取按关键字搜索到的商品数据。 通过该接口&#xff0c;您可以使用API Key和API Secret来认证身份&#xff0c;并使用…...

[计算机提升] Windows系统软件:娱乐类

3.3 系统软件&#xff1a;娱乐类 3.3.1 Windows Media Player&#xff1a;dvdplay Windows Media Player是Windows操作系统自带的多媒体播放软件&#xff0c;用于播放和管理电脑中的音频和视频文件。它提供了以下功能&#xff1a; 播放音频和视频文件&#xff1a;Windows Med…...

【Git企业开发】第五节.远程操作

文章目录 前言一、理解分布式版本控制系统二、远程仓库 2.1 新建远程仓库 2.2 克隆远程仓库 2.3 向远程仓库推送 2.4 拉取远程仓库总结 前言 一、理解分布式版本控制系统 我们目前所说的所有内容(工作区&#xff0c;暂存区&#xff0c;版本库等等)&#x…...

idea 配置checkstyle全过程

checkstyle是提高代码质量,检查代码规范的很好用的一款工具&#xff0c;本文简单介绍一下集成的步骤&#xff0c;并提供一份完整的checkstyle的代码规范格式文件&#xff0c;以及常见的格式问题的解决方法。 一&#xff0c;安装 打开idea的文件选项&#xff0c;选择设置&…...

小程序如何设置自动使用物流账号发货

小程序支持自动使用物流账号发货并生成运单号。商家需要与物流公司合作&#xff0c;获取物流账号&#xff0c;支持快递物流和同城外卖配送平台。具体方法请参考公众号之前发布的文章&#xff0c;例如可以搜索“快递账号”。 导入物流账号后&#xff0c;在小程序管理员后台->…...

高性能渲染——详解Html Canvas的优势与性能

本文由葡萄城技术团队原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 一、什么是Canvas 想必学习前端的同学们对Canvas 都不陌生&#xff0c;它是 HTML5 新增的“画布”元素&#x…...

2023.10 各个编程语言 受欢迎指数 排行

目录 一、前言: 二、排行: 三、趋势: 四、历史排名: 五、名人堂: 一、前言: 来自tiobe...

『PyQt5-基本控件』| 15 如何设置主窗口居中?退出应用程序如何操作?

15 如何设置主窗口居中?退出应用程序如何操作? 1 如何实现主窗口居中显示?1.1 获取屏幕坐标1.2 获取窗口坐标1.3 居中计算1.4 移动位置1.5 完整代码1.6 效果演示2 如何退出应用程序?2.1 使用按钮退出2.2 信号与槽绑定2.3 布局和增加按钮2.4 定义一个按钮事件2.5 完整代码2.…...

scrapy+selenium框架模拟登录

目录 一、cookie和session实现登录原理 二、模拟登录方法-Requests模块Cookie实现登录 三、cookiesession实现登录并获取数据 四、selenium使用基本代码 五、scrapyselenium实现登录 一、cookie和session实现登录原理 cookie:1.网站持久保存在浏览器中的数据2.可以是长期…...

【实验五】题解

T1&#xff1a;缺失的数字 题目描述; 我是敦立坤的爹&#xff01;&#xff01;&#xff01; 一个整数集合中含有n个数字&#xff0c;每个数字都在0n之间。假设0n的n1个数字中有且仅有一个数字不在该集合中&#xff0c;请找出这个数字。 分析&#xff1a; 这里引用一个桶的思…...

Android开发知识学习——Kotlin基础

函数声明 声明函数要用用 fun 关键字&#xff0c;就像声明类要用 class 关键字一样 「函数参数」的「参数类型」是在「参数名」的右边 函数的「返回值」在「函数参数」右边使用 : 分隔&#xff0c;没有返回值时可以省略 声明没有返回值的函数&#xff1a; fun main(){println…...

C++——定义一个 Book(图书)类

完整代码&#xff1a; /*定义一个 Book(图书)类&#xff0c;在该类定义中包括数据成员和成员函数 数据成员&#xff1a;book_name &#xff08;书名&#xff09;、price(价格)和 number(存书数量)&#xff1b; 成员函数&#xff1a;display()显示图书的 情况&#xff1b;borro…...

深度学习之基于YoloV5的道路地面缺陷检测系统(UI界面)

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、道路地面缺陷检测系统四. 总结 一项目简介 基于YoloV5的道路地面缺陷检测系统利用深度学习中的目标检测算法&#xff0c;特别是YoloV5算法&am…...

AcWing94. 递归实现排列型枚举:输出1~n的全排列

题目 把 1∼ n n n 这 n n n 个整数排成一行后随机打乱顺序&#xff0c;输出所有可能的次序。 输入格式 一个整数 n n n。 输出格式 按照从小到大的顺序输出所有方案&#xff0c;每行 1 个。 首先&#xff0c;同一行相邻两个数用一个空格隔开。 其次&#xff0c;对于两…...

神经网络多种注意力机制原理和代码讲解

多种注意力表格&#xff1a; 大神参考仓库链接&#xff1a; 魔鬼面具 对应 name 就是目录&#xff0c;点击即可跳转到对应学习。 nameneed_chaneelpaper SE (2017) Truehttps://arxiv.org/abs/1709.01507 BAM (2018) Truehttps://arxiv.org/pdf/1807.06514.pdf CBAM (2018) Tr…...

前端HTML

文章目录 一、什么是前端前端后端 前端三剑客1.什么是HTML2.编写前端的步骤1.编写服务端2.浏览器充当客户端访问服务端​ 3.浏览器无法正常展示服务端内容(因为服务端的数据没有遵循标准)4.HTTP协议>>>:最主要的内容就是规定了浏览器与服务端之间数据交互的格式 3. 前…...

Jenkins安装(Jenkins 2.429)及安装失败解决(Jenkins 2.222.4)

敏捷开发与持续集成 敏捷开发 敏捷开发以用户的需求进化为核心&#xff0c;采用迭代、循序渐进的方法进行软件开发。在敏捷开发中&#xff0c;软件项目在构建初期被切分成多个子项目&#xff0c;各个子项目的成果都经过测试&#xff0c;具备可视、可集成和可运行使用的特征。…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...