JAVA基础-数据结构一(线性表、链表、栈、队列)

一、数组线性表(ADT)

线性表:又称动态数组,核心是动态数组,可以自行扩容,支持增删改查四种功能

java中有ArrayList也可以自行扩容,二者功能较为相似,且ArrayList也支持转换为数组。

ArrayList<String> list=new ArrayList<>();
int size=list.size();  
//转换为String类型数组
String[] array = (String[])list.toArray(new String[size]);
//转换为int类型数组
int[] arr = list.stream().mapToInt(k -> k).toArray();

 1.定义成员变量(泛型)

private E[] array;//定义一个泛型数组
private int size;//数组内元素的实际数量
public MyArray(int capacity)
{this.array=(E[]) new Object[capacity];this.size=0;//size代表数组里实际有效的数据数量
}

2. 添加元素

 添加指定的元素,线性表有可能元素已满,需要扩容

扩容后(或未扩容)再添加元素,并将元素数量+1

public void add(E element)
{//数组按照顺序添加元素//如果实际元素数量已达到数组长度,判断为线性表已满//线性表已满则扩容if(size>=array.length)resize();array[size]=element;size++;
}

3. 插入元素

输入指定元素和要插入的位置下标

需要进行两个判断:

1.需要判断插入的位置是否合法(别超出线性表已有的范围)

2.如果线性表现在已满,就扩容

 判断过后,实现插入:for循环解决,给指定位置赋值为输入元素即可

别忘了最后增加元素数量

 public void insert(E element,int index) throws IndexOutOfBoundsException {//插入元素必须按照顺序插入,并且插入次数达到数组长度时才能扩容if(index<0 || index>size)//判断数组是否越界{throw new IndexOutOfBoundsException("超出数组范围");}if(size>=array.length)//如果实际元素达到数组容量上限{//数组扩容resize();}//实现数组插入for (int i = size-1; i >=index; i--) {array[i+1]=array[i];}array[index]=element;//插入元素size++;}

4. 删除元素

输入要删除元素的位置下标

需要判断该位置是否超出线性表范围

判断不超出后,执行删除:一个for循环解决

记得让元素数量-1

public void delete(int index) throws IndexOutOfBoundsException 
{//删除指定位置的数组元素if(index<0||index>size){throw new IndexOutOfBoundsException("数组越界,删除失败");}for(int i=index;i<size-1;i++){array[i]=array[i+1];}size--;}

5. 线性表扩容

扩容

新建一个数组,数组范围为原数组的两倍

然后把旧数组复制到新数组里

把新数组命名为旧数组的名字(这样就可以继续使用旧数组的名字) 

而原旧数组已经被抛弃。

public void resize()
{//数组扩容E[] newArray=(E[]) new Object[array.length*2];//把旧数组的内容复制到新的数组中System.arraycopy(array,0,newArray,0,array.length);this.array=newArray;
}

6.输出

public void Print()
{for (int i = 0; i < size; i++) {System.out.print(array[i]+" ");}
}

7.主函数试验

public static void main(String[] args) {MyArray a=new MyArray(4);for(int i=0;i<5;i++)a.add(i);//0 1 2 3 4a.insert(9,2);//0 1 9 2 3 4a.delete(4);//0 1 9 2 4a.Print();}

8.完整代码

public class MyArray<E> {private E[] array;//定义一个泛型数组private int size;//数组内元素的实际数量public MyArray(int capacity){this.array=(E[]) new Object[capacity];this.size=0;//size代表数组里实际有效的数据数量}public void add(E element){//数组按照顺序添加元素if(size>=array.length)resize();array[size]=element;size++;}//数组插入元素public void insert(E element,int index) throws IndexOutOfBoundsException {//插入元素必须按照顺序插入,并且插入次数达到数组长度时才能扩容if(index<0 || index>size)//判断数组是否越界{throw new IndexOutOfBoundsException("超出数组范围");}if(size>=array.length)//如果实际元素达到数组容量上限{//数组扩容resize();}//实现数组插入for (int i = size-1; i >=index; i--) {array[i+1]=array[i];}array[index]=element;//插入元素size++;}public void delete(int index) throws IndexOutOfBoundsException {//删除指定位置的数组元素if(index<0||index>size){throw new IndexOutOfBoundsException("数组越界,删除失败");}for(int i=index;i<size-1;i++){array[i]=array[i+1];}size--;}public void resize(){//数组扩容E[] newArray=(E[]) new Object[array.length*2];//把旧数组的内容复制到新的数组中System.arraycopy(array,0,newArray,0,array.length);this.array=newArray;}public void Print(){for (int i = 0; i < size; i++) {System.out.print(array[i]+" ");}}public static void main(String[] args) {MyArray a=new MyArray(4);for(int i=0;i<5;i++)a.add(i);a.insert(9,2);a.delete(4);a.Print();}
}

二、链表

java自带的List列表结构void add(E element)在列表末尾添加元素E get(int index)获取指定索引位置的元素E set(int index,E element)替换指定索引位置的元素E remove(int index)移除指定索引位置的元素int size()返回表的大小

我们用自定义类重新实现List的单链表版本

包括:增删改查功能

优点:
线性表逻辑上相邻,物理上也相邻,可随机存取任意元素。
缺点:
线性表插入、删除操作需要移动大量元素
存储空间是预分配的,不灵活,空间浪费,表的存储空间难扩充 

 1.定义成员变量

java里面没有像C语言的结构体,但java有内部类

新建一个内部类Node表示链表内的单个节点,内部类中包括

        1.元素

        2.指向下一节点的指针

        3.构造函数给元素赋值

构造好节点类,再新建头结点和尾结点指针,并新建size表示链表的有效长度

    private static class Node<E>{//定义一个结点内部类E data;Node next;//指向下一结点的指针Node(E data){this.data=data;}}private Node head;//头结点private Node last;//尾结点private int size;//链表实际长度

2. 查找节点

输入想要查找的节点下标,返回该下标位置的节点

新建一个指针,从头结点遍历到下标位置,返回指针指到下标位置的节点

    public Node get(int index)throws Exception{//获取指定下标位置的结点if(index<0 || index>=size)throw new IndexOutOfBoundsException("超出范围");Node temp=head;for (int i = 0; i < index; i++) {temp=temp.next;//指针后移}return temp;}

3. 插入节点

输入要插入的节点元素值,和要插入的位置下标

新建一个结点存储该结点元素值

先将要插入的节点指针指向插入位置的下一节点

然后再让插入位置的前一节点指向新结点

获取前一节点,可使用第二步定义的“查找节点”方法,输入位置-1下标

插入头结点、尾结点、中间某一节点的三种情况不同

    public void insert(E data,int index)throws Exception{if(index<0 || index>size)throw new IndexOutOfBoundsException("超出链表表长");Node insertNode=new Node(data);//定义待插入结点if(size==0){//空链表head=insertNode;last=insertNode;}else if(index==0){//插入到头结点前面insertNode.next=head;//把原头结点放在待插入元素的下一个位置上head=insertNode;//把待插入元素放置在头结点上}else if(index==size){//插入到尾结点后面last.next=insertNode;//先把待插入结点放在尾结点的下一个位置last=insertNode;//再把待插入节点设置为尾结点,也就是指针后移了一位}else{//插入中间位置Node prevNode=get(index-1);//设置插入位置的前结点insertNode.next=prevNode.next;//先让待插入结点指向插入位置结点prevNode.next=insertNode;//再让前结点指向待插入结点}size++;}

4. 删除节点

 输入要删除节点的下标

如果为空表删不了

新建一个节点指针,指向将要被删除的节点(垃圾桶)

要删除谁,就把谁的值赋给垃圾桶指针,然后再让前一结点指向后一结点

删除头结点、尾结点、中间某一节点情况不同

    public void delete(int index)throws Exception{if(index<0 || index>=size){throw new IndexOutOfBoundsException("删除失败,超出有效链表长度");}if(size==0){//空链表System.out.println("链表中无有效结点,删除失败");}Node removeNode=new Node(null);if(index==0){//删除head结点removeNode=head;//把旧的头结点设置为已删除结点head=head.next;//把头结点的下一个结点设置为新的头结点}else if(index==size-1){//删除尾结点removeNode=last;//把旧的尾结点设置为已删除Node prevNode=get(size-2);//获取前结点prevNode.next=null;//让前结点指向空last=prevNode;//设置前结点为新的尾结点}else{//删除中间节点Node prevNode=get(index-1);//获取前结点Node nextNode=prevNode.next.next;//获取删除节点的下一节点removeNode = prevNode.next;prevNode.next=nextNode;//让前结点指向后节点}size--;}

5. 输出节点

    public void output(){Node temp=head;//设置一个结点指针指向头结点for (int i = 0; i < size; i++) {//遍历链表System.out.print(temp.data+" ");temp=temp.next;}}

 6.主函数检验

    public static void main(String[] args) throws Exception{MyList<Integer> LinkList=new MyList<>();LinkList.insert(3,0);//3LinkList.insert(8,1);//3->8LinkList.insert(3,2);//3->8->3LinkList.insert(8,3);//3->8->3->8LinkList.insert(9,1);//3->9->8->3->8LinkList.delete(0);//9->8->3->8LinkList.output();}

7.完整代码

/*
* java自带的List列表结构
* void add(E element)在列表末尾添加元素
* E get(int index)获取指定索引位置的元素
* E set(int index,E element)替换指定索引位置的元素
* E remove(int index)移除指定索引位置的元素
* int size()返回表的大小*//*数据结构就是用自定义类实现List结构:增删改查*/
public class MyList<E> 
{private static class Node<E>{//定义一个结点内部类E data;Node next;//指向下一结点的指针Node(E data){this.data=data;}}private Node head;//头结点private Node last;//尾结点private int size;//链表实际长度//查找节点public Node get(int index)throws Exception{//获取指定下标位置的结点if(index<0 || index>=size)throw new IndexOutOfBoundsException("超出范围");Node temp=head;for (int i = 0; i < index; i++) {temp=temp.next;//指针后移}return temp;}//链表插入元素public void insert(E data,int index)throws Exception{if(index<0 || index>size)throw new IndexOutOfBoundsException("超出链表表长");Node insertNode=new Node(data);//定义待插入结点if(size==0){//空链表head=insertNode;last=insertNode;}else if(index==0){//头插insertNode.next=head;//把原头结点放在待插入元素的下一个位置上head=insertNode;//把待插入元素放置在头结点上}else if(index==size){//尾差last.next=insertNode;//先把待插入结点放在尾结点的下一个位置last=insertNode;//再把待插入节点设置为尾结点,也就是指针后移了一位}else{//插入中间位置Node prevNode=get(index-1);//设置插入位置的前结点insertNode.next=prevNode.next;//先让待插入结点指向插入位置结点prevNode.next=insertNode;//再让前结点指向待插入结点}size++;}//链表删除元素public void delete(int index)throws Exception{if(index<0 || index>=size){throw new IndexOutOfBoundsException("删除失败,超出有效链表长度");}if(size==0){//空链表System.out.println("链表中无有效结点,删除失败");}Node removeNode=new Node(null);if(index==0){//删除head结点removeNode=head;//把旧的头结点设置为已删除结点head=head.next;//把头结点的下一个结点设置为新的头结点}else if(index==size-1){//删除尾结点removeNode=last;//把旧的尾结点设置为已删除Node prevNode=get(size-2);//获取前结点prevNode.next=null;//让前结点指向空last=prevNode;//设置前结点为新的尾结点}else{//删除中间节点Node prevNode=get(index-1);//获取前结点Node nextNode=prevNode.next.next;//获取删除节点的下一节点removeNode = prevNode.next;prevNode.next=nextNode;//让前结点指向后节点}size--;}//输出链表public void output(){Node temp=head;//设置一个结点指针指向头结点for (int i = 0; i < size; i++) {//遍历链表System.out.print(temp.data+" ");temp=temp.next;}}public static void main(String[] args) throws Exception {MyList<Integer> LinkList=new MyList<>();LinkList.insert(3,0);LinkList.insert(8,1);LinkList.insert(3,2);LinkList.insert(8,3);LinkList.insert(9,1);LinkList.delete(0);LinkList.output();}
}

三、栈

Java自带栈
Stack<E> stack=new Stack<>();
boolean stack.empty()                 测试此堆栈是否为空
E stack.pop()                         出栈
E stack.push(E item)                  入栈
E stack.peek()                        获取栈顶元素
int stack.search(Object o)            返回对象在堆栈里的位置下标

栈是后进先出的,经典例子如:弹夹压弹,羽毛球筒等

后面会附有实际运用的题目

栈的应用场景:

栈的输出顺序和输入顺序相反,所以栈通常用于对“历史”的回溯,也就是逆流而上追溯“历史”

例如实现递归的逻辑,就可以用栈来代替,因为栈可以回溯方法的调用链。 

栈还有一个著名的应用场景是面包屑导航,使用户在浏览页面时可以轻松地回
溯到上一级或更上一级页面。

1. 定义成员变量

栈由数组来实现,栈内实际元素的数量用size来记录

    private E[] arr;//将元素存到数组中private int size;//栈的实际长度(元素数量)public MyStack(){//调用无参构造方法 默认最大容量12this(12);}public MyStack(int MaxSize) {this.arr=(E[])new Object[MaxSize];}

 2.判断栈是否为空

    public boolean isEmpty(){//判断是否为空栈return this.size==0;}

3. 入栈

元素自栈顶入栈,栈顶为数组[size]

判断栈是否已满,已满就扩容

把元素加入到栈顶,记得有效长度+1

    public E push(E value){//入栈if(this.size == arr.length){//栈满扩容E[] copyArr=(E[])new Object[arr.length*2];arr=copyArr;}this.arr[size]=value;this.size++;return value;}

4.获取栈顶元素

判断栈空

把栈顶元素返回

    public E get(){//获取栈顶元素if(isEmpty()){System.out.println("栈为空");return null;}return arr[size-1];}

 5.出栈

判断栈空

先把栈顶元素存起来,然后清除栈顶元素

再把栈的有效长度-1 

    public E pop(){//出栈if(isEmpty()){//栈空抛出异常throw new RuntimeException("栈中无元素");}E top=arr[size-1];//size始终比栈顶元素的下标多1arr[size]=null;size--;return top;}

6. 返回栈的长度

    public int getSize() {//返回数组大小return this.size;}

7. 打印栈

由于栈是只能通过一次出栈一个栈顶元素来遍历

而遍历结束,栈也就空了

因此要新建一个栈,把原栈输出的栈顶元素都存起来

等原栈遍历结束为空栈后,再把新建栈内存的元素再依次遍历入栈到原栈里

这样就保证了打印结束后,原栈内元素不变

    public void print(){MyStack<E> stack=new MyStack<>();//新建栈while(!isEmpty())//遍历到栈空(也可以改成输入要遍历的元素数量){E elem=this.pop();//存储栈顶元素并出栈//栈顶元素为null说明是数组冗余的部分,非有效元素if(elem==null){continue;}stack.push(elem);//把原栈栈顶元素入栈到新建栈System.out.print(elem+" ");}System.out.println();while(!stack.isEmpty()){//把新建栈的栈顶依次赋值给原栈E elem=stack.pop();this.push(elem);}}

 8.主函数检验

    public static void main(String[] args) {MyStack<Integer> stack=new MyStack<>();for (int i = 0; i < 11; i++) {stack.push(i);//入栈}stack.print();//10 9 8 7 6 5 4 3 2 1 0stack.pop();//10System.out.println(stack.get());//9System.out.println(stack.getSize());//10}

9.完整代码

/*
* Java自带栈
* Stack<E> stack=new Stack<>();
* boolean stack.empty() 测试此堆栈是否为空
* E stack.pop() 出栈
* E stack.push(E item)入栈
* E stack.peek() 获取栈顶元素
* int stack.search(Object o)返回对象在堆栈里的位置下标*//*
* java数据结构就是要实现java自带的堆栈的方法
* 了解堆栈实现的原理*/public class MyStack<E> {private E[] arr;//将元素存到数组中private int size;//栈的实际长度(元素数量)public MyStack(){//调用无参构造方法 默认最大容量12this(12);}public MyStack(int MaxSize) {this.arr=(E[])new Object[MaxSize];}public boolean isEmpty(){//判断是否为空栈return this.size==0;}public E get(){//获取栈顶元素if(isEmpty()){System.out.println("栈为空");return null;}return arr[size-1];}public E push(E value){//入栈if(this.size == arr.length){//栈满扩容E[] copyArr=(E[])new Object[arr.length*2];arr=copyArr;}this.arr[size]=value;this.size++;//栈的实际长度,始终比栈顶元素的下标多1return value;}public E pop(){//出栈if(isEmpty()){//栈空抛出异常throw new RuntimeException("栈中无元素");}E top=arr[size-1];arr[size]=null;size--;return top;}public int getSize() {//返回数组大小return this.size;}public void print(){MyStack<E> stack=new MyStack<>();while(!isEmpty()){E elem=this.pop();if(elem==null){continue;}stack.push(elem);System.out.print(elem+" ");}System.out.println();while(!stack.isEmpty()){E elem=stack.pop();this.push(elem);}}public static void main(String[] args) {MyStack<Integer> stack=new MyStack<>();for (int i = 0; i < 11; i++) {stack.push(i);//入栈}stack.print();//10 9 8 7 6 5 4 3 2 1 0stack.pop();//10System.out.println(stack.get());//9System.out.println(stack.getSize());//10}
}

四、队列

JAVA自带Queue队列接口
LinkedList(双向链表)、ArrayList均可实现Queue
boolean add(E element):         将指定的元素添加到队列的末尾,如果成功则返回true,                                      如果队列已满则抛出异常。
boolean offer(E element)        同上,如果队列已满返回false;
E remove()                      移除并返回队列头部元素,如果队列为空抛出异常
E poll()                        同上,如果队列为空返回null
E element()                     获取队列头部的元素,但不移除,队列为空抛出异常
E peek()                        同上,队列为空返回null
int size()                      返回队列中元素个数
boolean isEmpty()               判断队列是否为空
clear()                         清空
contains(Object o)              是否包含某元素

使用自定义类实现队列,满足先进先出的原则,实现循环队列 

队列的应用:

队列的输出顺序和输入顺序相同,所以队列通常用于对“历史”的回放,也就 是按照“历史”顺序,把“历史”重演一遍。

例如在多线程中,争夺公平锁的等待队列,就是按照访问顺序来决定线程在队 列中的次序的。

再如网络爬虫实现网站抓取时,也是把待抓取的网站URL存入队列中,再按照存 入队列的顺序来依次抓取和解析的。 

1.定义成员变量

队列元素由数组实现,定义一个头部指针和一个尾部指针

队列长度由new MyQueue(int MaxSize)决定

需要注意,由于循环队列的定义,出于判断队空还是队满的区分,只要队不空,头指针和尾指针永远至少隔一个位置

也就是说,队列里的实际元素数量永远比队列长度少1

    private E[] arr;private int front;//头部指针private int rear;//尾部指针public MyQueue(int MaxSize){arr=(E[])new Object[MaxSize];}

2. 判断队列是否为空

初始位置,头指针和尾指针都没动 

    public boolean isEmpty(){return rear==front;//头指针等于尾指针,队列无元素}

3. 入队

先判断队列是否已满,判断已满的方法是,(尾指针+1)%队列长度==头指针

如果未满,就为尾指针赋值,需注意,队列为循环队列,尾指针的位置取决于头指针的位置

因此尾指针的位置需要%长度,表示在一个循环里

添加元素后,尾指针+1

    public boolean offer(E element) throws Exception {//判断队列是否已满,已满返回falseif((rear+1)%arr.length==front){System.out.println("队列已满");return false;}arr[rear%arr.length]=element;rear=(rear+1)%arr.length;//队尾指针后移一位return true;}

4. 出队

判断队空

存储队首的元素后,清除队首元素后把头指针后移一位,就能达到出队的效果 

    public E poll() throws Exception {//如果队列为空,返回nullif(isEmpty()){System.out.println("队列为空");return null;}E element=arr[front];//存储需要出队的元素arr[front]=null;front=(front+1)%arr.length;//队头指针后移一位return element;}

5. 获取队首元素

    public E getElement(){//判断是否为空,为空返回nullif(isEmpty())return null;return arr[front];}

6. 获取队列长度

    public int size(){return (rear+arr.length-front)% arr.length;}

7. 清空队列

    public boolean clear(){E[] newArr=(E[]) new Object[arr.length];arr=newArr;front=rear=0;//必须让指针回归零的位置return true;}

8. 队列是否包含某元素

    public boolean contains(E element){if(isEmpty())return false;for (E e : arr) {if(e==element)return true;}return false;}

9. 输出队列

    public void print(){for (int i = front; i != rear; i=(i+1)%arr.length) {System.out.print(arr[i]+" ");}System.out.println();}

10.主函数检验

public static void main(String[] args) throws Exception {MyQueue<Integer> myque=new MyQueue<>(5);myque.offer(1);//入队rear0->1myque.offer(2);//rear1->2myque.offer(3);//rear2->3myque.offer(4);//rear3->4myque.poll();//1出队 front0->1myque.poll();//2出队 front1->2myque.offer(5);//5入队 rear4->5->0myque.print();//3 4 5 rear==0 front==2System.out.println(myque.getElement());//3System.out.println(myque.contains(4));//trueSystem.out.println(myque.contains(1));//falsemyque.offer(3);//入队 rear0->1+1==front队列已满myque.offer(8);//myque.offer(9);myque.print();//3 4 5 3队列实际可存储元素为arr.length-1个也就是4个System.out.println(myque.clear());//清空myque.offer(888);myque.print();//888}

11.完整代码

import java.util.Scanner;
/*
* JAVA自带Queue队列接口
* LinkedList(双向链表)、ArrayList均可实现Queue
* boolean add(E element): 将指定的元素添加到队列的末尾,如果成功则返回true,如果队列已满则抛出异常。
* boolean offer(E element)同上,如果队列已满返回false;
* E remove() 移除并返回队列头部元素,如果队列为空抛出异常
* E poll() 同上,如果队列为空返回null
* E element()获取队列头部的元素,但不移除,队列为空抛出异常
* E peek() 同上,队列为空返回null
* int size()返回队列中元素个数
* boolean isEmpty() 判断队列是否为空
* clear()清空
* contains(Object o)是否包含某元素*/
public class MyQueue<E> 
{private E[] arr;private int front;//头部指针private int rear;//尾部指针public MyQueue(int MaxSize){arr=(E[])new Object[MaxSize];}//判断是否为空public boolean isEmpty(){return rear==front;//头指针等于尾指针,队列无元素}//入队public boolean offer(E element) throws Exception {//判断队列是否已满,已满返回falseif((rear+1)%arr.length==front){System.out.println("队列已满");return false;}arr[rear%arr.length]=element;rear=(rear+1)%arr.length;//队尾指针后移一位return true;}//出队public E poll() throws Exception {//如果队列为空,返回nullif(isEmpty()){System.out.println("队列为空");return null;}E element=arr[front];//存储需要出队的元素arr[front]=null;front=(front+1)%arr.length;//队头指针后移一位return element;}//获取队首元素public E getElement(){//判断是否为空,为空返回nullif(isEmpty())return null;return arr[front];}//返回队列中的元素个数public int size(){return (rear+arr.length-front)% arr.length;}//清空public boolean clear(){E[] newArr=(E[]) new Object[arr.length];arr=newArr;front=rear=0;//必须让指针回归零的位置return true;}//是否包含某元素public boolean contains(E element){if(isEmpty())return false;for (E e : arr) {if(e==element)return true;}return false;}//输出队列public void print(){for (int i = front; i != rear; i=(i+1)%arr.length) {System.out.print(arr[i]+" ");}System.out.println();}public static void main(String[] args) throws Exception {MyQueue<Integer> myque=new MyQueue<>(5);myque.offer(1);//入队rear0->1myque.offer(2);//rear1->2myque.offer(3);//rear2->3myque.offer(4);//rear3->4myque.poll();//1出队 front0->1myque.poll();//2出队 front1->2myque.offer(5);//5入队 rear4->5->0myque.print();//3 4 5 rear==0 front==2System.out.println(myque.getElement());//3System.out.println(myque.contains(4));//trueSystem.out.println(myque.contains(1));//falsemyque.offer(3);//入队 rear0->1+1==front队列已满myque.offer(8);//myque.offer(9);myque.print();//3 4 5 3队列实际可存储元素为arr.length-1个也就是4个System.out.println(myque.clear());//清空myque.offer(888);myque.print();//888}
}

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

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

相关文章

中国大学生计算机设计大赛--智慧物流挑战赛基础

文章目录 一、Ubuntu基础1.1 基本操作1.2 文本编辑 二、ROS基础介绍2.1 概念与特点2.2 基本结构2.3 创建工程2.4 节点和节点管理器2.5 启动文件 三、ROS通信机制3.1 话题3.2 服务3.3 动作3.4 参数服务器 四、ROS可视化工具4.1 rviz4.2 rqt4.3 tf 五、Python实现简单的ROS节点程…

01-分析同步通讯/异步通讯的特点及其应用

同步通讯/异步通讯 微服务间通讯有同步和异步两种方式 同步通讯: 类似打电话场景需要实时响应(时效性强可以立即得到结果方便使用),而且通话期间不能响应其他的电话(不支持多线操作)异步通讯: 类似发邮件场景不需要马上回复并且可以多线操作(适合高并发场景)但是时效性弱响应…

MQ高可用相关设置

文章目录 前言MQ如何保证消息不丢失RabbitMQRocketMQKafkaMQ MQ如何保证顺序消息RabbitMQRocketMQKafka MQ刷盘机制/集群同步RabbitMQRocketMQKafka 广播消息&集群消息RabbitMQRocketMQ MQ集群架构RabbitMQRocketMQKafka 消息重试RabbitMQRockeMqKafka 死信队列RocketMQKaf…

Claude3横空出世:颠覆GPT-4,Anthropic与亚马逊云科技共启AI新时代

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

洛谷P3853路标设置

题目背景 B 市和 T 市之间有一条长长的高速公路&#xff0c;这条公路的某些地方设有路标&#xff0c;但是大家都感觉路标设得太少了&#xff0c;相邻两个路标之间往往隔着相当长的一段距离。为了便于研究这个问题&#xff0c;我们把公路上相邻路标的最大距离定义为该公路的“空…

车载电子电器架构 —— 汽车电子电气系统分解

车载电子电器架构 —— 汽车电子电气系统分解 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何…

【JavaWeb】【瑞吉外卖】分页操作数据传输转换

瑞吉day3 搞定了分页以及数据传输的问题 mybatis-plus分页接口实现 分页主要是通过mybatis提供的接口实现的。这篇笔记只是记录如何实现这个接口&#xff0c;并不会深究原理。 博主也比较菜&#xff0c;目前还没有手撕mybatis代码&#xff0c;后续有机会研究一下&#xff08;…

【操作系统概念】第14章:系统保护

文章目录 0. 前言14.1 保护目标14.2 保护原则14.3 保护域14.3.1 域结构14.3.2 实例&#xff1a;UNIX14.3.3 实例&#xff1a;MUTICS 14.4 访问矩阵14.5 访问矩阵的实现14.5.1 全局表14.5.2 对象的访问列表14.5.3 域的能力(权限)列表14.5.4 锁-钥匙机制*14.5.5 比较* 14.6 访问控…

Github 2024-03-10php开源项目日报Top10

根据Github Trendings的统计,今日(2024-03-10统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量PHP项目10Blade项目1Laravel:表达力和优雅的 Web 应用程序框架 创建周期:4631 天开发语言:PHP, BladeStar数量:75969 个Fork数量:24281 次…

网络层学习常见问题及答案整理

问题0&#xff1a;ARP解析协议的定义和特点 ARP&#xff08;地址解析协议&#xff09;高速缓存表用于存储IP地址到MAC地址的映射关系。当一台主机需要将IP数据包发送到同一局域网中的另一台主机时&#xff0c;它需要知道目标主机的MAC地址&#xff0c;以便在以太网帧中使用。AR…

Vue脚手架

Vue脚手架 学习目标&#xff1a; 理解Node.js基本使用方法理解包资源管理器NPM的使用理解webpack的作用理解 vue-cli 脚手架 (重点)Element-UI 组件库 1.vue的格式&#xff1a;new Vue({//作用的视图el:"id选择器",//vue中的数据/*data:{key:value,key:value,...}…

Mysql实现分布式锁

Mysql实现分布式锁 Mysql实现分布式锁 Mysql实现分布式锁 通过数据库的唯一索引和事务的特性来实现分布式锁。 自定义一个表 -- 创建分布式锁表 CREATE TABLE DistributedLock(lock_key VARCHAR(64) NOT NULL,lock_value VARCHAR(255),PRIMARY KEY (lock_key) );-- 尝试获取…

Java 基于微信小程序的快递柜小程序

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

harmony 鸿蒙安全和高效的使用N-API开发Native模块

简介 N-API 是 Node.js Addon Programming Interface 的缩写&#xff0c;是 Node.js 提供的一组 C API&#xff0c;封装了V8 引擎的能力&#xff0c;用于编写 Node.js 的 Native 扩展模块。通过 N-API&#xff0c;开发者可以使用 C 编写高性能的 Node.js 模块&#xff0c;同时…

【python3】线程同步机制 Condition

threading.Condition 是 Python 中用于线程同步的一种机制&#xff0c;它提供了一个条件变量&#xff0c;允许一个或多个线程等待某个条件变为真时再继续执行。Condition 对象内部包含一个锁对象&#xff0c;线程可以在调用 wait() 方法时释放这个锁&#xff0c;并在条件满足时…

devops-Jenkins【内网环境部署及插件安装】

1、准备工作 外网Linux机器一台&#xff0c;内网Linux机器一台。硬件环境要求&#xff1a;至少1GB的可用内存空间&#xff0c;至少50GB的可用硬盘空间。软件环境需求&#xff1a;需要安装好Java8&#xff0c;Java的运行环境JRE1.8或者Java的开发工具包JDK1.8都可以。 2、外网安…

结构指针的使用

结构指针的使用 指针类型变量&#xff1a; 指针类型&#xff0c;是变量类型的一种&#xff0c;它是专门用来存储变量的地址的。 例如 int *p; 表示p是一个指针变量&#xff0c;它用来存储某个整型变量的地址。 int a5; int *p&a; 这样&#xff0c;就将整型变量a的地…

体系班第十三节

1判断完全二叉树递归做法 有四种情况&#xff1a;1 左树完全&#xff0c;右数满&#xff0c;且左高为右高加一 2左满 &#xff0c;右满&#xff0c;左高为右高加一 3左满&#xff0c;右完全&#xff0c;左右高相等 4左右均满且高相等 #include<iostream> #include&l…

转移表回调函数实现

回调函数实现 计算器的模拟&#xff08;函数指针数组的使用&#xff09;&#xff08;回调函数&#xff09; 简化 冗余 老的代码的问题就是 冗余 写死 不能完成不同的任务 函数调用的时候只需要知道地址就可以 calc计算器 这里也称之为转移表 #define _CRT_SECURE_NO_WAR…

出现“error: failed to push some refs to ‘https://github.com/****.git‘”,如何解决问题

一、出错情况&#xff1a; 今天继续推送整理的知识点的时候&#xff0c;出现了一个报错。“error: failed to push some refs to https://github.com/.git”&#xff0c;百思不得其解&#xff0c;之前推送的时候都可以轻松推送成功&#xff0c;如今却说本地库与远程库不一致。…