数据结构与算法java实战篇--链表

news2024/11/16 9:54:15

目录

        一.链结点

        二.单链表

        1.单链表的插入方法insertFirst()

        2.单链表的删除方法deleteFirst()

        3.链表显示displayList()

        4.单链表代码:

三. 查找和删除指定链结点

 四.双端链表 

五.用链表实现的栈

六.用链表实现队列 

七.有序链表

八.双向链表

        1.遍历 

        2.插入

        3.删除


一.链结点

        在链表中,每一个数据项都包含在链结点中,一个链结点是某个类的对象,这个类叫Link,因为一个类有许多类似的结点,所有有必要用一个不同于链表的类来表达链结点,每个Link对象都包含一个对下一个链结点引用的字段next,但是链表本身的对象中一个字段指向对第一个链结点的引用

链结点 Link的定义:

class Link{
public int iData;
public double dData;
public Link next;
}

二.单链表

单链表的操作:

·在链表头插入一个数据项

·在链表头删除一个数据项

·遍历链表显示它的内容

1.单链表的插入方法insertFirst()

链表插入:

定义一个新的链表结点,让新结点连接旧结点,再让头结点连接新结点

插入insertFirst()代码:

public void insertFirst(int id,double dd){
Link newLink=new Link(id,dd);
newLink.next=first;
first=newLink;
}

2.单链表的删除方法deleteFirst()

链表删除:

通过把first重新指向第二个链结点,断开和第一个链结点的连接

deleteFirst():

public Link deleteFirst(){
Link temp=first;
first=first.next;
return temp;
}

3.链表显示displayList()

代码:

public void displayList(){
System.out.print("List(fist—>last):");
Link current=first;
while(current!=null){
current.displayLink();
current=current.next;
}
System.out.print("");
}

4.单链表代码:

class Link{   //定义链表
    public int iData;
    public double dData;
    public Link next;
    public void displayLink(){
        System.out.print("{"+iData+","+dData+"}");
    }
    public Link(int id,double dd){
        iData=id;
        dData=dd;
    }
}

class LinkList{   //定义单链表
    private Link first;
    public LinkList(){
        first=null;
    }
    public boolean isEmpty(){   //链表是否为空
        return (first==null);
    }
    public void insertFirst(int id,double dd){    //单链表插入操作
        Link newLink=new Link(id,dd);
        newLink.next=first;
        first=newLink;
    }
    public Link delectFirst(){   //删除操作
        Link temp=first;
        first=first.next;
        return temp;
    }
    public void displayList(){   //显示单链表
        System.out.println("List(first—>last):");
        Link current=first;
        while (current!=null){
            current.displayLink();
            current=current.next;
        System.out.println(" ");
        }
    }
}

三. 查找和删除指定链结点

        查找的实现:通过一个current变量开始时指向first,然后通过不断地把自己赋值为current.next,沿着链表向前移动,如果要查找的值和链表的值相同,就返回链表结点的引用,如果没有找到就返回null

        删除操作的实现:删除操作先寻找到要删除的结点,然后将前一个结点和后一个结点连接,实现删除操作

代码:

public class CollectionDemo {
    public static void main(String[] args) {
        LinkList linkList = new LinkList();
       linkList.insertFirst(1,12);
       linkList.insertFirst(2,23);
       linkList.insertFirst(3,34);
        linkList.displayList();
        Link j=linkList.find(2);
        System.out.println("第二个元素为:"+j.dData);
        Link d=linkList.delect(1);
        System.out.println("删除第一个元素后:");
        linkList.displayList();
    }
}

class Link {  //链表结点
    public int iData;
    public double dData;
    public Link next;  //链表结点初始化

    public Link(int id, double dd) {
        this.dData = dd;
        this.iData = id;
    }
    //显示数据
    public void displayLink() {
        System.out.print("{" + iData + "," + dData + "}");
    }
}
//链表定义
class LinkList{
    private Link first;
    public LinkList(){
        first=null;
    }

    //插入操作
    public void insertFirst(int id,double dd){
        Link newLink=new Link(id,dd);
        newLink.next=first;
        first=newLink;
    }

    //查找操作
    public Link find(int key){
        Link current=first;
        while(current.iData!=key){
            if (current.next==null)
                return null;
            else current=current.next;
        }
        return current;    //返回查找的链结点引用
    }

    //删除操作
    public Link delect(int key){
        Link current=first;   //查询结点
        Link previous=first;  //前置结点
        while (current.iData!=key){
            //如果没有找到指定结点
            if (current.next==null)
                return null;
            else {
                previous=current;   //设置前置结点
                current=current.next; //继续查询
            }
        }
            //找到指定结点
            if (current==first)//指定结点为头结点
                first=first.next;
            else
                previous.next=current.next;
            return current;
        }

        //显示列表
    public void displayList(){
        System.out.println("List(first-->last):");
        Link current=first;
        while (current!=null){
            current.displayLink();
            System.out.print(" ");
            current=current.next;
        }
        System.out.println(" ");
    }
    }

效果:


 四.双端链表 

        双端链表与传统链表相似,但它多了一个特性,就是对最后一个结点的引用可以像在链表头结点一样,在链表尾插入一个链结点

双端链表的插入操作: 

 双端链表代码:

public class CollectionDemo {
    public static void main(String[] args) {
     FirstLastList firstLastList=new FirstLastList();
     firstLastList.insertFirst(1);
     firstLastList.insertFirst(2);
     firstLastList.insertFirst(3);
     firstLastList.insertLast(4);  //末尾插入
     firstLastList.displayList();
     //输出:List(first-->last):
        //3 2 1 4  
    }
}

class Link{  //链表结点
    public long dData;
    public Link next;
    public Link(long d){
        dData=d;
    }
    public void displayLink(){
        System.out.print(dData+" ");
    }
}

class FirstLastList{
    private Link first;
    private Link last;
    public FirstLastList(){
        first=null;
        last=null;
    }
    public boolean isEmpty(){ //判断是否为空
        return first==null;
    }
    public void insertFirst(long dd){ //表头插入
        Link newLink=new Link(dd);
        if(isEmpty())  //如果表头为空,连接last
            last=newLink;
        //如果表头不为空
        newLink.next=first;
        first=newLink;
    }
    public void insertLast(long dd){  //表尾插入
        Link newLink=new Link(dd);
        if (isEmpty())  //如果表头为空,
            first=newLink;
        else  //如果表头不为空
            last.next=newLink;
        last=newLink;
    }
    public long deleteFirst(){   //删除元素
        long temp=first.dData;
        if (first.next==null)
            last=null;
        first=first.next;
        return temp;
    }
    public void displayList(){   //输出链表
        System.out.println("List(first-->last):");
        Link current=first;
        while(current!=null){
            current.displayLink();
            current=current.next;
        }
        System.out.println(" ");
    }
}

五.用链表实现的栈

栈相关内容可以学习:数据结构与算法java实战篇--队列和栈

代码实现:

public class CollectionDemo {
    public static void main(String[] args) {
     LinkStack linkStack=new LinkStack();
     linkStack.push(1);
     linkStack.push(2);
     linkStack.push(3);
     linkStack.push(4);
     linkStack.displayStack();
     linkStack.pop();  //先进后出,'4'出栈
     linkStack.displayStack();
    }
}

class Link{
    public long dData;
    public Link next;
    public Link(long dd){
        dData=dd;
    }
    public void displayLink(){  //显示结点
        System.out.print(dData+" ");
    }
}
//定义链表
class LinkList{
    private Link first;
    public LinkList(){  //链表初始化
        first=null;
    }
    public boolean isEmpty(){  //判断是否为空
        return (first==null);
    }
    public void insertFirst(long dd){ //插入操作
        Link newLink=new Link(dd);
        newLink.next=first;
        first=newLink;
    }
    public long deleteFirst(){  //删除操作
        Link temp=first;
        first=first.next;
        return temp.dData;
    }
    public void displayList(){
        Link current =first;
        while(current!=null){
            current.displayLink();
            current=current.next;
        }
        System.out.println(" ");
    }
}
//链表实现
class LinkStack{
    private LinkList theList;
    public LinkStack(){
        theList=new LinkList();
    }
    public void push(long i){  //入栈操作
        theList.insertFirst(i);
    }
    public long pop(){  //出栈操作
        return theList.deleteFirst();
    }
    public boolean isEmpty(){  //判断栈是否为空
        return (theList.isEmpty());
    }
    public void displayStack(){
        System.out.print("Stack(top-->bottom):");
        theList.displayList();
    }
}

效果:


六.用链表实现队列 

代码:

public class CollectionDemo {
    public static void main(String[] args) {
    LinkQueue linkQueue=new LinkQueue();
        linkQueue.insert(1);
        linkQueue.insert(2);
        linkQueue.insert(3);
        linkQueue.insert(4);
        linkQueue.insert(5);
        linkQueue.displayQueue();
        linkQueue.remove();  //队列先进先出
        linkQueue.displayQueue();
    }
}

class Link{
    public long dData;
    public Link next;
    public Link(long dd){
        dData=dd;
    }
    public void displayLink(){  //显示结点
        System.out.print(dData+" ");
    }
}
//定义链表
class FirstLastList{
    private Link first;
    private Link last;
    public FirstLastList(){
        first=null;
        last=null;
    }
    public boolean isEmpty(){
        return (first==null);
    }
    public void insertLast(long dd){ //队列头出尾进
        Link newLink=new Link(dd);
        if(isEmpty())
            first=newLink;
        else
            last.next=newLink;
        last=newLink;
    }
    public long deleteFrist(){  //队列头删除
        long tamp= first.dData;
        if(first.next==null)
            last=null;
        first=first.next;
        return tamp;
    }
    public void displayList(){  //输出元素
        Link current=first;
        while(current!=null){
            current.displayLink();
            current=current.next;
        }
        System.out.println(" ");
    }
}
//链表实现队列
class LinkQueue{
    private FirstLastList theList;
    public LinkQueue(){
        theList=new FirstLastList();
    }
    public boolean isEmpty(){  //判断是否为空
        return theList.isEmpty();
    }
    public void insert(long i){  //入队操作
        theList.insertLast(i);
    }
    public long remove(){   //出队操作
        return theList.deleteFrist();
    }
    public void displayQueue(){  //显示队列
        System.out.println("Queue(first-->last):");
        theList.displayList();
    }
}

效果:


七.有序链表

有序链表在插入数据时,链表会先查找插入数据一个插入的位置,再进行插入操作

 有序链表(升序)的实现:

public class CollectionDemo {
    public static void main(String[] args) {
  SortedList sortedList=new SortedList();
  sortedList.insert(34);
  sortedList.insert(21);
  sortedList.insert(52);
  sortedList.insert(93);
  sortedList.insert(48);
  sortedList.displayList();     
    }
}

 class Link{
    public long dData;
    public Link next;
    public Link(long dd){
        dData=dd;
    }
    public void displayLink(){
        System.out.print(dData+" ");
    }
 }
class SortedList{  //有序链表
    private Link first;
    public SortedList(){
        first=null;
    }
    public boolean isEmpty(){
        return (first==null);
    }
    public void insert(long key){   //按升序插入
        Link newLink=new Link(key);
        Link previous=null;
        Link current=first;
        while(current!=null&&key>current.dData){   //按升序查找key插入位置
            previous=current;  //前置位
            current=current.next;  //向后查询
        }
        //找到对应插入位置
        if (previous==null)  //插入为的前置位为空,直接插入
            first=newLink;
        else   //前置位不为空,前置位previous连接key结点,key结点连接current,实现插入
            previous.next=newLink;
        newLink.next=current;
    }
    public Link remove(){  //删除操作
        Link temp=first;
        first=first.next;
        return temp;
    }
    public void displayList(){  //输出数据
        System.out.print("List(first-->last):");
        Link current=first;
        while(current!=null){
            current.displayLink();
            current=current.next;
        }
        System.out.println(" ");
    }
}

按升序的有序链表结果:


八.双向链表

双向链表允许向前遍历,也允许向后遍历

1.遍历 

        双向链表的遍历方法displayForward()方法和普通链表的displayList()方法相同,displayBackward()方法与它们类似,但是从表尾开始,displayBackward方法部分代码如下:

Link current = first;
while(current!=null)
    current = current.previous;


2.插入

        双向链表的插入方法有三个,insertFirst()方法在表头插入,insertLast()方法在表尾插入,insertAfter()在某一特定元素后面插入

insertFirst()方法:除非链表是空的,否则insertFirst()方法把原来的first指向的链接点的previous字段指向新链接点,把新链接点的next字段指向前者,最后把first指向新结点

如果链表是空的,last字段必须改变,insertFirst核心部分代码:

if(isEmpty())
    last=newLink;
else
    first.previous=newLink;
newLink.next=first;
first=newLink;

 insertLast()方法:该方法和insertFirst方法类似

insertAlter()方法:四个链接过程

  实现代码:

if(current==last){
newLink.next=null;
last=newLink;
}else{
newLink.next=current.next;
current.next.previous=newLink;
}
newLink.preious=current;
current.next=newLink;

3.删除

        删除方法有deleteFirst(),deleteLast()和deleteKey(),前两个较简单。在deleteKey()中要删除的链结点是current所值的链结点,如果输出的结点既不是第一个结点,也不是第一个结点,入图:

 如果被删除的结点是第一个或最后一个,那就产生特殊情况,因为first或last必须指向前一个或后一个链结点,下面是实现代码:

    if(current==first)
        first=current.next;
    else
        current.previous.next=current.next;
    if(current==last)
        last=current.previous;
    else
        current.next.previous=current.previous;
        

双向链表实现代码:

class Link{
    public long dData;
    public Link next;
    public Link previous;
    public Link(long d){
        dData=d;
    }
    public void displayLink(){
        System.out.print(dData+" ");
    }
}
//双向链表
class DoublyLinkedList{
    private Link first;
    private Link last;
    public DoublyLinkedList(){
        first=null;
        last=null;
    }
    public boolean isEmpty(){
        return first==null;
    }
    public void insertFirst(long dd){  //头插
        Link newLink=new Link(dd);
        if(isEmpty())
            first=newLink;
        else
            first.previous=newLink;  //newlink<--oldlast
        newLink.next=first;        //newlink-->oldlast
        first=newLink;          //first-->newlink;
    }
    public void insertLast(long dd){  //尾插
        Link newLink=new Link(dd);
        if (isEmpty()){
            first=newLink;
        }else{
            last.next=newLink;  //oldlast-->newlink
            newLink.previous=last;  //oldlas<--newlink
        }
        last=newLink;    //last-->newlink
    }
    public Link deleteFirst(){   //头删除
        Link temp=first;
        if(first.next==null)
            last=null;
        else
            first.next.previous=null;   //oldlast-->null
        first=first.next;    //first-->oldlast
        return temp;
    }
    public Link deleteLast(){  //尾删除
        Link temp=last;
        if (first.next==null)
            last=null;
        else
            last.previous.next=null;    //oldprivous-->null
        last=last.previous;       //last-->oldprivous
        return temp;
    }
    public boolean insertAfter(long key,long dd){   //将dd插入到key后面
        Link current=first;
        while(current.dData!=key){
            current=current.next;
            if (current==null)    //找不到插入对象的位置
                return false;
        }
        //找到要插入的位置
        Link newLink=new Link(dd);
        if (current==last){    //如果插入的对象是最后一个
            newLink.next=null;   //newLink-->null
            last=newLink;        //last-->newlink
        }else {
            newLink.next=current.next;   //如果不是最后一个,newlink-->oldnext
            current.next.previous=newLink;  //oldnext-->newlink
        }
        newLink.previous=current;  //current<--newlink
        current.next=newLink;     //current-->newlink
        return true;
    }
    public Link deleteKey(long key){   //删除指定元素
        Link current=first;
        while (current.dData!=key){
            current=current.next;
            if (current==null)   //如果没有指定元素
                return null;
        }
        //找到要删除的指定元素
        if(current==first)  //如果删除的元素是头结点
            first=current.next;   //first-->oldnext
        else   //不是头结点
            current.previous.next=current.next;  //oldprevious-->oldnext
        if(current==last) //如果删除的元素是尾结点
            last=current.previous;  //last-->old.previous
        else
            current.next.previous=current.previous;  //oldprevious<--oldnext
        return current;
    }
    public void displayForward(){  //正向输出
        System.out.print("List(first-->last):");
        Link current=first;
        while (current!=null){
            current.displayLink();
            current=current.next;
        }
        System.out.println(" ");
    }
    public void displayBackward() {  //反向输出
        System.out.print("List(last-->first):");
        Link current = last;
        while (current != null) {
            current.displayLink();
            current = current.previous;
        }
        System.out.println(" ");
    }
}

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

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

相关文章

“量子深度学习的春天是否已来?” | CNCC论坛分享

2022年12月8日举办的CNCC2022“量子深度学习的春天是否已来&#xff1f;”技术论坛&#xff0c;从学术、技术和产业的角度出发&#xff0c;深入探讨未来5到10年深度学习发展在算力方面的瓶颈问题、量子深度学习会给AI领域带来何种演变以及量子深度学习的技术落地是否依然久远等…

代码随想录Day58|739. 每日温度、496.下一个更大元素 I

文章目录739.每日温度496.下一个更大元素 I739.每日温度 文章讲解&#xff1a;代码随想录 (programmercarl.com) 题目链接&#xff1a;739. 每日温度 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 请根据每日 气温 列表&#xff0c;重新生成一个列表。对应位置…

weidl x DeepRec:热门微博推荐框架性能提升实战

微博推荐团队&#xff1a;陈雨、韩楠、蔡小娟、高家华 1.项目背景 热门微博是新浪微博的重要功能之一&#xff0c;包含热门流、热点流、频道流、小视频后推荐、视频社区等场景。 标推荐首页 发现页推荐 沉浸视频题weidl机器学习框架为热门微博在线学习提供模型训练和推理服务…

【问题记录与解决】ModuleNotFoundError: No module named ‘pymongo‘ 并测试代码

目录 一、问题记录二、解决方法一(不一定好使)三、法二(亲测可以使用)四、安装 pymongo 的目的一、问题记录 报错内容是缺少对应的模块, ModuleNotFoundError: No module named pymongo… 二、解决方法一(不一定好使) 直接在PyCharm中下载 pymongo模块即可。 但是这…

试卷安全分发系统

摘要 高校教务管理过程中&#xff0c;试卷以明文形式传输和集中存储&#xff0c;存在数据泄漏安全隐患。现提出了一个基于数字证书的试卷防泄漏方案&#xff0c;采用算法加密试卷&#xff0c;试卷在传输过程中中以密文的形式传输&#xff0c;每次传输的时候都会对试卷进行签名…

CadQuery二维Sketch教程

2D草图是3D CAD的基础。本文介绍如何在CadQuery中使用不同的方法构建二维草图&#xff08;Sketch&#xff09;。 1、基于面的 API 构建2D草图的主要方法是基于构建面并使用布尔运算将它们组合起来。 import cadquery as cqresult (cq.Sketch().trapezoid(4,3,90).vertices…

【GO】 K8s 管理系统项目[API部分--StatefulSet]

K8s 管理系统项目[API部分–StatefulSet] 1. 接口实现 service/dataselector.go // statefulSetCell type statefulSetCell appsv1.StatefulSetfunc(s statefulSetCell) GetCreation() time.Time {return s.CreationTimestamp.Time }func(s statefulSetCell) GetName() stri…

河道水文标尺监测系统 OpenCv

河道水文标尺监测系统借助PythonOpenCv深度学习架构模型对江河湖泊进行全天候不间断实时检测&#xff0c;当PythonOpenCv深度学习架构模型监测到水位异常时&#xff0c;立即抓拍存档告警&#xff0c;同步告警截图和视频推送给相关人员。OpenCV的全称是Open Source Computer Vis…

JUC之ABA问题

什么是ABA问题&#xff1f; ABA问题是由CAS而导致的一个问题 CAS算法实现一个重要前提需要取出内存中某时刻的数据并在当下时刻比较并交换&#xff0c;那么在这个时间差内会导致数据的变化。 比如说一个线程一从内存位置V中取出A&#xff0c;这是另一个线程二也从内存中取出…

从注解入手理解springboot原理

一、理解注解 1、注解是什么&#xff1f; 注解可以理解为一个标记或者标签&#xff0c;范围可以是类、方法、属性。 2、自定义一个注解&#xff0c;进行理解spring的自动装配。 自定义自己的注解&#xff1a;JDK官方提供提供了一些基础元注解&#xff0c;就是标记注解的注解…

Android设计模式详解之状态模式

前言 状态模式中的行为是由状态来决定的&#xff0c;不同的状态下有不同的行为。 状态模式和策略模式的结构几乎完全一样&#xff0c;但他们的目的、本质却完全不一样。 状态模式的行为是平行的、不可替换的&#xff0c;而策略模式的行为是彼此独立、可互相替换的。 状态模式把…

满足耐压24V的USB3.0 USB3.1 Type-C防静电器件

什么是USB3.1 Type-C 现有的USB 2.0协议允许高达480Mbps的数据传输速率&#xff0c;并支持即插即用、热插拔安装和运行。与之相比&#xff0c;USB 3.0规范允许高达5Gbps的数据传输速率&#xff0c;并向后支持较低速的USB 2.0规范。 USB 3.0增加了4个接到连接器的新引脚&#…

湖北移动M411A_ZN-S905L3AB-UWE5621DS原机制作语音线刷包

湖北移动M411A_ZN-S905L3AB-UWE5621DS原机制作语音线刷包&#xff0c;打开原机屏蔽的WIFI&#xff0c;设置、首页、语音正常。 固件特点&#xff1a; 1、修改dns&#xff0c;三网通用&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、无开机广告&am…

非零基础自学Golang 第16章 正则表达式 16.1 正则表达式介绍 16.2 正则表达式语法

非零基础自学Golang 文章目录非零基础自学Golang第16章 正则表达式16.1 正则表达式介绍16.2 正则表达式语法16.2.1 普通字符16.2.2 字符转义16.2.3 元字符16.2.4 限定符16.2.5 定位符16.2.6 分组构造16.2.7 匹配模式第16章 正则表达式 正则表达式&#xff08;Regular Expressi…

Docker高级:Redis集群实战!4主4从缩容到3主3从,怎么处理?

在上一篇,我们学会了redis集群的扩容。从3主3从扩容到4主4从。 那么,接着,活动过去了。流量没有那么大了。需要缩容了。从4主4从缩容到3主3从了。那么这个时候又该怎么处理呢? PS本系列:《Docker学习系列》教程已经发布的内容,凯哥会在文末加上。 缩容思考问题: 1:…

TypeScript 前端工程最佳实践

作者&#xff1a;王春雨 前言 随着前端工程化的快速发展&#xff0c; TypeScript 变得越来越受欢迎&#xff0c;它已经成为前端开发人员必备技能。 TypeScript 最初是由微软开发并开源的一种编程语言&#xff0c;自2012年10月发布首个公开版本以来&#xff0c;它已得到了人们…

Docker自定义镜像上传阿里云

目录 1. alpine 简介 2. 基于alpine构建jdk8镜像 2.1 Dockerfile 2.2 将构建目录上传到linux中 2.3 执行构建 3. 镜像瘦身 4. 上传阿里云镜像仓库 1. alpine 简介 Alpine Linux是一个轻型Linux发行版&#xff0c;它不同于通常的Linux发行版&#xff0c;Alpine采用了mus…

斯坦福联合Meta提出多模态模型RA-CM3,检索增强机制或成文本图像领域新制胜法宝

原文链接&#xff1a;https://www.techbeat.net/article-info?id4403 作者&#xff1a;seven_ 论文链接&#xff1a; https://arxiv.org/abs/2211.12561 相信目前很多AI大模型研究者都会遇到一个非常困难的问题&#xff0c;那就是很难控制的模型参数和容量&#xff0c;由于参与…

【Three.js入门】纹理及其常用属性、透明纹理、环境遮挡贴图与强度

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;也会涉及到服务端 &#x1f4c3;个人状态&#xff1a; 在校大学生一枚&#xff0c;已拿多个前端 offer&#xff08;秋招&#xff09; &#x1f680;未…

消息队列—RabbitMQ(万字详解)

消息队列—RabbitMQ 笔记整理自 【涛哥】最适合小白入门的RabbitMQ教程 1. 消息队列介绍 Ⅰ. 消息队列需求场景 在基于微服务开发的电商项目中&#xff0c;商品的查询和商品的修改是通过两个服务实现的&#xff0c;如果修改了商品的价格&#xff0c;如何保证商品查询服务查询出…