【数据结构】链表

news2024/11/23 7:21:02

目录

一、线性表接口

二、单链表

2.1 单链表的结构定义

2.2 头插法

2.3中间位置的插入

2.4尾插法

2.5遍历链表

2.6查询线性表中是否包含指定元素

 2.7返回索引为index的元素值

2.8修改索引为index位置的元素为新值,返回修改前的元素值

2.9删除链表中索引为index的元素,返回删除前的元素值

2.10删除第一个值为val的元素

2.11在表中删除所有值为val的元素

三、带头单链表dummyHead

3.1结构定义

3.2中间位置的插入

3.3头插法和尾插法

 3.4遍历带头链表

3.5 在表中删除所有值为val的元素

 四、用递归写链表的方法

4.1链表指定位置的插入

4.2链表的正向输出

4.3链表的反向输出

五、ArrayList和LinkedList的区别


数组这种结构适用于频繁查询低频插入和修改的场景,若频繁插入和删除时,由于需要进行元素的搬移以及扩容等操作,浪费空间,性能开销较大,因此引入了链表。

链表是逻辑连续的,不是物理连续的。

物理连续指的是前一个元素一定是位于后一个元素之前,典型的就是数组。

逻辑连续是指每一个结点之间通过一个“钩子”连接,没有这个钩子,每个节点之间是彼此独立的毫无关系。优点就是可以在任意结点之前或者之后插入新的结点,对其他的节点并不造成影响。不需要考虑空间是否够用以及扩容问题,不会造成空间的浪费。

由于链表可以根据是否带头结点、是否循环、是否双向,排列组合有8中结构,只需要考虑三种结构:带向不带头的单链表(单向链表),单项带头链表,双向不带头链表。


一、线性表接口

定义线性表接口Seqlist。定义接口带来的好处:就是可以以非常低的成本来更换具体的子类。

public interface SeqList {
    void add(int val);
    // 在索引为index的位置插入新元素
    void add(int index,int val);
    // 查询线性表中是否包含指定元素val
    boolean contains(int val);
    // 返回索引为index的元素值
    int get(int index);
    // 修改索引为index位置的元素为新值,返回修改前的元素值
    int set(int index,int newVal);
    // 删除线性表中索引为index的元素,返回删除前的元素值
    int removeByIndex(int index);
    // 删除第一个值为val的元素
    void removeByValueOnce(int val);
    // 在线性表中删除所有值为val的元素
    void removeAllValue(int val);
}

二、单链表

有两个特殊的结点:头结点:只有头结点没有前驱。尾结点:只有尾结点没有后继。

单链表只能从前向后遍历,无论是插入还是删除方法在链表中都要找到操作位置的前驱结点。

2.1 单链表的结构定义

val表示该结点中存储的数值,next属性保存下一个结点的地址,若没有下一个结点则为null。

size表示该链表中保存的有效元素个数,head 保存了第一个结点的地址。

public class MyLinkedList implements SeqList {
    private int size;
    private Node head;
    private  class Node {
        private int val;
        private Node next;
        public Node(int val) {
            this.val = val;
        }
    }
}

2.2 头插法

必须先让新结点先挂在原先头结点的前面,然后再让head指向新的结点。

    public void addFirst(int val) {
        Node node = new Node(val);
        node.next = head;
        head = node;
        size ++ ;
    }

2.3中间位置的插入

首先要排除不合法的情况,然后根据index的特殊索引选择头插法,然后剩下的情况再继续分析,首先需要遍历该列表停在index位置的前驱节点,然后将该位置的next指向新的node,将node的next修改为原位置的next,最后size++。

    public void add(int index, int val) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("add index illegal!");
        }
        if (index == 0) {
            addFirst(val);
            return;
        }
        Node prev = head;
        for (int i = 1; i <index; i++) {
            prev = prev.next;
        }
        Node node = new Node(val);
        node.next = prev.next;
        prev.next = node;
        size++;
    }

2.4尾插法

尾插法不必全部写出,在按照索引插入中,index == size时就是尾插, 并且同样是有前驱节点,尾结点本来指向的就是空,所以新的尾结点也应该指向空。所以尾插法中写入 add(size,val)即可。

    public void add(int val) {
        add(size,val);
    }

2.5遍历链表

不能直接使用head进行遍历,遍历一次之后,头结点的地址就找不到了。所以创建一个n使他等于head,用n进行遍历。

    public String toString() {
        StringBuilder sb = new StringBuilder();
        for(Node n = head;n!=null;n = n.next){
            sb.append(n.val);
            sb.append("->");
            if(n.next == null){
                sb.append("NULL");
            }
        }
        return sb.toString();
    }
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(1);
        myLinkedList.add(3);
        myLinkedList.add(5);
        myLinkedList.addFirst(7);
        myLinkedList.add(2,10);
        System.out.println();
    }

 调用三种添加方法,尾插3,头插1,尾插5,头插7,在索引为3的位置插入4。最后的结果应为1,3,5,4,7。

402e48a38a364180836a97bcbd9980d7.png

2.6查询线性表中是否包含指定元素

创建一个Node类型的n使他等于head,然后遍历整个链表,当第一次遇见n的val等于指定元素,即返回true。如果遍历到最后还是没有,则返回false。遍历到最后意味着n==null。

    public boolean contains(int val) {
        for(Node n = head;n!= null;n = n.next){
            if(n.val == val){
                return true;
            }
        }
        return false;
    }
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.add(3);
        myLinkedList.addFirst(1);
        myLinkedList.add(5);
        myLinkedList.add(7);
        myLinkedList.add(3,4);
        System.out.println(myLinkedList.toString());
        System.out.println(myLinkedList.contains(40));
        System.out.println(myLinkedList.contains(4));
    }

77184a55a1594a11a71e0794ff97b8b0.png

 2.7返回索引为index的元素值

首先要创建一个rangeCheck来判断index是否合法。然后遍历链表,找到索引为index的结点,返回该结点的值。

    public int get(int index) {
        if(!rangCheck(index)){
            throw new IllegalArgumentException("get index illegal!");
        }
        Node node = head;
        for(int i = 0;i<index;i++){
            node = node.next;
        }
        return node.val;
    }

    private boolean rangCheck(int index) {
        return index >= 0 && index < size;
    }
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.add(3);
        myLinkedList.addFirst(1);
        myLinkedList.add(5);
        myLinkedList.add(7);
        myLinkedList.add(3,4);
        System.out.println(myLinkedList.toString());
        System.out.println(myLinkedList.get(2));
    }

9e365547745a41df85a5e455532baa4f.png

2.8修改索引为index位置的元素为新值,返回修改前的元素值

    public int set(int index, int newVal) {
        if(!rangCheck(index)){
            throw new IllegalArgumentException("get index illegal!");
        }
        Node node = head;
        for(int i = 0;i<index;i++){
            node = node.next;
        }
        int temp = node.val;
        node.val = newVal;
        return temp;
    }
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.add(3);
        myLinkedList.addFirst(1);
        myLinkedList.add(5);
        myLinkedList.add(7);
        myLinkedList.add(3,4);
        System.out.println(myLinkedList.toString());
        System.out.println(myLinkedList.set(4,9));
        System.out.println(myLinkedList.toString());
        System.out.println(myLinkedList.set(0,10));
        System.out.println(myLinkedList.toString());
        System.out.println(myLinkedList.set(2,20));
        System.out.println(myLinkedList.toString());
    }

fbe55d969e6840c1b20ec9004e3f1fde.png

2.9删除链表中索引为index的元素,返回删除前的元素值

这个方法可以引申出链表的另外两个方法,删除头结点和尾结点。只需要调用该函数并且把index设置为0或者size-1。

想要删除在索引位置上的元素,就需要找到该位置的前驱结点,使前驱节点的与索引位置的next结点连接,这时候就有一个特殊情况,头结点是没有前驱结点的,所以需要把头结点单独分析。

排除不合法的情况后,现针对index == 0来分析,直接将head = head.next即可,同时要让长度减一。剩下的情况只需要找到index位置的前驱结点,使它的next = index位置的next。

    public int removeFirst(){
       return removeByIndex(0);
    }
    public int removeLast(){
        return removeByIndex(size-1);
    }
    public int removeByIndex(int index) {
        if(!rangCheck(index)){
            throw new IllegalArgumentException("get index illegal!");
        }
        if(index ==0){
            int tmp = head.val;
            head = head.next;
            size--;
            return tmp;
        }
        Node node = head;
        for(int i = 1;i<index;i++){
            node = node.next;
        }
        int tmp = node.next.val;
        node.next = node.next.next;
        size--;
        return tmp;
    }
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.add(1);
        myLinkedList.add(3);
        myLinkedList.add(5);
        myLinkedList.add(7);
        myLinkedList.add(3,4);
        System.out.println(myLinkedList.toString());
        System.out.println(myLinkedList.removeFirst());
        System.out.println(myLinkedList.removeLast());
        System.out.println(myLinkedList.removeByIndex(1));
        System.out.println(myLinkedList.toString());
    }

 先删除头结点,然后删除尾结点,再删除下标为1的数。

f3c6b3f98e1d4bb0a2b257c878dd6f87.png

2.10删除第一个值为val的元素

想要删除值为的元素,就需要找到它的前驱结点,使前驱节点的与查找元素的后继结点连接,这种时候也需要将头结点单独来看,因为头结点没有前驱结点。

并且如果链表为null这种情况也要分开处理,因为链表为空代表链表中没有值处理不了。

逻辑上的终止条件(假设要删除位置的前驱结点为prev):此处删除的是prev的后继节点,因此保证prev的后继节点必须存在,所以终止条件是prev.next != null。

    public void removeByValueOnce(int val) {
        if(head == null){
            return ;
        }
        if(head.val==val){
            int tmp = head.val;
            head = head.next;
            size--;
            return ;
        }
        for(Node prev = head;prev.next!= null;prev = prev.next){
            if(prev.next.val== val){
                prev.next = prev.next.next;
                size--;
                return;
            }
        }
    }
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.add(7);
        myLinkedList.add(1);
        myLinkedList.add(3);
        myLinkedList.add(7);
        myLinkedList.add(5);
        myLinkedList.add(3,4);
        myLinkedList.add(7);
        System.out.println(myLinkedList.toString());
        myLinkedList.removeByValueOnce(7);
        System.out.println(myLinkedList.toString());
        myLinkedList.removeByValueOnce(7);
        System.out.println(myLinkedList.toString());
        myLinkedList.removeByValueOnce(7);
        System.out.println(myLinkedList.toString());
    }

5293d15625c244cdb570f7c33bbec098.png

2.11在表中删除所有值为val的元素

若链表为空则直接返回,若链表的头结点就是待删除的结点,需要考虑删除后补上的结点的值也是val,所以需要进行while循环,直到head的值不是val,在这种情况中需要让head!=null ,否则无法取得head的val值。

进行完这一步,head可能为空,也可能head的值不是val。同样创建prev进行遍历使 prev= head。所以需要先保证prev不为空,才能取得prev.next的val值。

删除一个结点之后不能直接使prev引用向后走,prev引用直到prev.next.val != val时prev才能向后走,否则如果补上的结点值也为val则会被忽略。

    public void removeAllValue(int val) {
        if(head == null){
            return ;
        }
        while (head!=null&&head.val==val){
            int tmp = head.val;
            head = head.next;
            size--;
        }
        if(head == null){
            return ;
        }
        Node prev = head;
        while(prev.next!=null){
            if(prev.next.val== val){
                prev.next = prev.next.next;
                size--;
            }else {
                prev = prev.next;
            }
        }
    }
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.add(7);
        myLinkedList.add(7);
        myLinkedList.add(3);
        myLinkedList.add(7);
        myLinkedList.add(7);
        myLinkedList.add(5);
        myLinkedList.add(3,4);
        myLinkedList.add(7);
        System.out.println(myLinkedList.toString());
        myLinkedList.removeAllValue(7);
        System.out.println(myLinkedList.toString());
    }

67a3bc3b3a354a3388ec5b60864c0a18.png

三、带头单链表dummyHead

在单链表的操作过程中,每次插入和删除都需要考虑头结点的情况,因为只有头结点特殊,没有前驱,所以需要想一个办法,让链表中所有的有效结点都一视同仁,就不需要区额外关注头结点的情况。

因此引入一种新的结构,虚拟头结点dummyHead,不存储具体的元素,只是作为链表的头来使用,所有存储元素的结点都是该头结点的后继结点。

3.1结构定义

与单链表不同的地方就是要在构造方法中先定义虚拟头结点。后来每一个结点都在虚拟头结点的后面。

public class LinkedListWithHead {
    private int size;
    private Node dummyHead;
    private static class Node {
        private int val;
        private Node next;
        public Node(int val) {
            this.val = val;
        }
    }
    public LinkedListWithHead(){
        this.dummyHead = new Node(-1);
    }
}

3.2中间位置的插入

首先排除不合法情况后不需要将第一个有效结点单独拿出来调用头插法,因为它也有前驱结点,所以可以一视同仁。

    public void add(int index, int val){
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("add index illegal!");
        }
        Node prev = dummyHead;
        for (int i = 0; i < index; i++) {
            prev = prev.next;
        }
        Node node = new Node(val);
        node.next = prev.next;
        prev.next = node;
        size++;
    }

3.3头插法和尾插法

 与单链表没有什么差别,就是将单链表的头结点换成了带头链表的虚拟头结点的后继节点。

    public void addFirst(int val){
        Node node = new Node(val);
        node.next = dummyHead.next;
        dummyHead.next = node;
        size++;
    }

 但是在带头链表中,第一个有效结点也有前驱节点,所以也可以像尾插法一样运用add方法。

    public void addFirst(int val){
        add(0,val);
    }
    public void addLast(int val) {
        add(size,val);
    }

 3.4遍历带头链表

经过链表之后,带头链表的遍历就很好写了,摘除头结点之后遍历即可。

    public String toString() {
        StringBuilder sb = new StringBuilder();
        Node cur = dummyHead.next;
        while (cur != null) {
            sb.append(cur.val);
            sb.append("->");
            if (cur.next == null) {
                sb.append("NULL");
            }
            cur = cur.next;
        }
        return sb.toString();
    }
    public static void main(String[] args) {
        LinkedListWithHead linkedListWithHead = new LinkedListWithHead();
        linkedListWithHead.addLast(3);
        linkedListWithHead.addLast(5);
        linkedListWithHead.addLast(9);
        linkedListWithHead.addFirst(1);
        linkedListWithHead.add(3,7);
        System.out.println(linkedListWithHead.toString());
    }

 先尾插3,5,9。然后头插1,在指定位置3插入7。

196b99151d3e41bc984633f142997bec.png

3.5 在表中删除所有值为val的元素

具体逻辑也是和单链表一样的,只是不需要特别考虑头结点。用cur指向虚拟头结点,来判断cur.next的val是否和需要判断的值相同,如果相同就将cur.next指向 cur.next.next,直到不相同的时候,就让cur向右移。

    public void removeAllValue(int val){
        Node cur = dummyHead;
        while (cur.next!=null){
            Node sec = cur.next.next;
            if(cur.next.val == val){
                cur.next = sec;
                size--;
            }else{
                cur = cur.next;
            }
        }
    }
    public static void main(String[] args) {
        LinkedListWithHead linkedListWithHead = new LinkedListWithHead();
        linkedListWithHead.addLast(1);
        linkedListWithHead.addLast(1);
        linkedListWithHead.addLast(3);
        linkedListWithHead.addLast(1);
        linkedListWithHead.addLast(5);
        linkedListWithHead.addLast(1);
        linkedListWithHead.addFirst(1);
        System.out.println(linkedListWithHead.toString());
        linkedListWithHead.removeAllValue(1);
        System.out.println(linkedListWithHead.toString());
    }

9a4842d212f84973a58572e2732640aa.png

 四、用递归写链表的方法

具体构造还是和之前一样。

public class LinkedListR implements SeqList {
    private int size;
    private Node head;
    private  class Node {
        private int val;
        private Node next;
        public Node(int val) {
            this.val = val;
        }
    }
}

4.1链表指定位置的插入

首先就是不合法情况的排除,然后先判断如果index==0就是头插法,如果index!=0,那么直接让head.next = add(head.next,index - 1,val),调用递归一直到找到index位置然后插入即可。

然后头插和尾插都调用这个方法输入对应的位置即可。

    public void addFirst(int val) {
        add(0,val);
    }

    @Override
    public void add(int val) {
        add(size,val);
    }

    @Override
    public void add(int index, int val) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("add index illegal!");
        }
        head = add(head,index,val);
    }
    private Node add(Node head, int index, int val) {
        if (index == 0) {
            Node node = new Node(val);
            node.next = head;
            head = node;
            size ++;
            return head;
        }
        head.next = add(head.next,index - 1,val);
        return head;
    }

4.2链表的正向输出

链表的正向输出用递归写也很简单,首先head==null时,输出NULL然后返回即可,然后先输出当前的值在调用递归,一个接一个输出。

    private void print(Node head) {
        if (head == null) {
            System.out.print("NULL\n");
            return;
        }
        System.out.print(head.val + "->");
        print(head.next);
    }
    public void print() {
        print(head);
    }

4.3链表的反向输出

用递归的方法反向输出会更加的容易,能倒叙从尾结点开始输出内容,一直到头结点。

首先当head==null时,直接返回就好,然后需要把先把子链表全部输出完,站在head位置,只要一直输出就好。但是这个时候最后输出没有办法加上null,正常正向输出最后会有null,所以创建一个变量count计数,在每次调用递归前count++。然后每次调用完递归返回后再count--,当count==0时,已经走到了链表的头结点,在最后要继续输出null。

    public void printReverse() {
        printReverse(head);
    }
    int count = 0;
    private void printReverse(Node head) {
        if (head == null) {
            return;
        }
        count ++;
        printReverse(head.next);
        count --;
        System.out.print(head.val + "->");
        if (count == 0) {
            System.out.print("NULL\n");
        }
    }
    public static void main(String[] args) {
        LinkedListR list = new LinkedListR();
        list.addFirst(1);
        list.addFirst(3);
        list.add(5);
        list.add(7);
        list.add(1,10);
        list.print();
        list.printReverse();
    }

08bf786edcd8419b816174925f69fc49.png

五、ArrayList和LinkedList的区别

不同点ArrayListLinkedList
存储空间上物理上一定连续逻辑上连续,但物理上不一定连续
随机访问支持O(1)

不支持:O(N)

头插需要搬移元素,效率低O(N)只需修改引用的指向,O(1)

插入

空间不够时需要扩容没有扩容的概念
应用场景元素高效存储+频繁访问任意位置插入和删除频繁

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

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

相关文章

公众号免费搜题系统

公众号免费搜题系统 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;点击…

嵌入式FreeRTOS学习十,任务调度和任务就绪链表任务调度过程

一.main函数里面的栈是哪里分配的 main函数里面用到的栈&#xff0c;假设为msp,是汇编代码里面设定的&#xff0c;对于STM32F103,在汇编代码里的向量表设置了一个栈_initial_sp,那这个栈是给谁用的呢&#xff1f; 可以看到&#xff0c;这个_initial_sp在内存中分配了一个空间区…

案例驱动,手把手教你学PyTorch(二)

通过案例学PyTorch。 扫码关注《Python学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 Autograd Autograd 是 PyTorch 的自动微分包。多亏了它&#xff0c;我们不需要担心偏导数、链式法则或类似的东西。 那么&#xff0c;我们如何告诉 PyTorch 做它的事情并计…

python在线及离线安装库

目录 一、配置python环境变量&#xff1a; 二、在线安装python库&#xff1a; 三、离线安装python库&#xff1a; 一、配置python环境变量&#xff1a; 1、以windows10为例&#xff0c;右键电脑->>属性: 2、选择高级系统设置&#xff1a; 3、选择环境变量&#xff1a…

八行代码一键照片转漫画

有些小程序可以实现照片转漫画的功能&#xff0c;本文和你一起来探索其背后的原理。用Python实现八行代码一键照片转漫画。    文章目录一、效果展示二、代码详解1 导入库2 照片转漫画一、效果展示 在介绍代码之前&#xff0c;先来看下本文的实现效果。    喜欢的小伙伴也…

操作系统主引导扇区代码是如何被加载到内存的?

1. 问题&#xff1a;OS引导代码为什么需要org 07c00h&#xff1f; 在前几天在知乎上的的一个回答《想带着学生做一个操作系统&#xff0c;可行性有多大&#xff1f;》中&#xff0c;我们引用了一段主引导扇区MBR中的操作系统加载代码&#xff1a; org 07c00h ; 告诉编译器程…

PCA实现降维的过程

PCA将相关性高的变量转变为较少的独立新变量&#xff0c;实现用较少的综合指标分别代表存在于各个变量中的各类信息&#xff0c;既减少高维数据的变量维度&#xff0c;又尽量降低原变量数据包含信息的损失程度&#xff0c;是一种典型的数据降维方法。PCA保留了高维数据最重要的…

web前端期末大作业 HTML+CSS+JavaScript仿京东

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 在线商城购物 | 水果商城 | 商城系统建设 | 多平台移动商城 | H5微商城购物商城项目| HTML期末大学生网页设计作业&#xff0c;Web大学生网页 HTML&am…

SpringBoot发送邮件

06.发送邮件 在使用javaSE时&#xff0c;我们会发现发送邮件较为麻烦&#xff0c;而在SpringBoot中&#xff0c;发送邮件就变成一件较为简单的时。 导入mail的maven的启动类。 <dependency><groupId>org.springframework.boot</groupId><artifactId>…

DSPE PEG Azide, DSPE-PEG-N3;磷脂聚乙二醇叠氮

中文名称&#xff1a;磷脂聚乙二醇叠氮(DSPE-PEG-N3) 中文别名&#xff1a;N-二硬脂酰磷脂酰乙酰胺-PEG-叠氮 磷脂PEG叠氮 英文名称&#xff1a;DSPE PEG Azide, DSPE-PEG-N3 性状&#xff1a;根据不同的分子量为固体或者粘稠液体。 溶剂&#xff1a;溶于DCM&#xff0c;…

表单标签。。

一、任务目标 掌握表单标签及其属性的使用 二、任务背景 HTML表单用于收集用户输入。表单元素指的是不同类型的 input 元素、复选框、单选按钮、提交按钮等。 三、任务内容 1、<form></form>标签 用于创建HTML表单&#xff0c;常用属性如下&#xff1a; action&…

OpenGL ES 学习(一) -- 基本概念

最近在研究 SurfaceView 和 TextureView&#xff0c;发现栅格化这东西&#xff0c;一直没怎么搞明白&#xff0c;一搜都是关于 OpenGL 的&#xff0c;没办法&#xff0c;当初也是要学习这个&#xff0c;现在重试拾起。 之前接触 OpenGL &#xff0c;是主要解决一个渲染模糊问题…

JavaEE-操作系统

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;JavaEE &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 目录操作系统介绍操作系统的定位进程进程控制块内存管理进程间通信思维导图总结操作系统介绍 操作系统是一组做计算机资源管理的软…

文献学习01_Attention Is All You Need_20221119

论文信息 Subjects: Computation and Language (cs.CL); Machine Learning (cs.LG) &#xff08;1&#xff09;题目&#xff1a;Attention Is All You Need &#xff08;你需要的就是关注&#xff09; &#xff08;2&#xff09;文章下载地址&#xff1a;https://doi.org/10.4…

今天给大家介绍一篇基于javaWeb的汽车订票系统的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

牛客网之SQL非技术快速入门(3)-排序、关联关系

知识点&#xff1a; &#xff08;1&#xff09;order by colunm_name(s) ASC|DESC order by ID ASC,name ASC,sex DESC 不写就是默认升序&#xff0c;DESC降序 &#xff08;2&#xff09;3中关联关系&#xff1a;left join、right join、inner join/join 21、现在运营想要查…

【微信开发第四章】SpringBoot实现微信H5支付

前言 在进行微信公众号业务开发的时候,微信支付可以说是非常重要的一环。该篇文章每一步都有记录&#xff0c;力争理解的同时各位小伙伴也能够实现功能 文章目录前言1、公众号配置2、微信支付实现代码总结1、公众号配置 1、绑定域名 先登录微信公众平台进入“设置与开发”&…

阿里云架构实战之ALB(应用型负载均衡)介绍与搭建

ALB介绍 服务器端负载均衡SLB&#xff08;Server Load Balancer&#xff09;是一种对流量进行按需分发的服务&#xff0c;通过将流量分发到不同的后端服务来扩展应用系统的服务吞吐能力&#xff0c;并且可以消除系统中的单点故障&#xff0c;提升应用系统的可用性。 阿里云负…

代码随想录算法训练营第60天 | 一刷结束篇 84.柱状图中最大的矩形

代码随想录系列文章目录 一刷总结篇 文章目录代码随想录系列文章目录84.柱状图中最大的矩形dp 普通思路单调栈一刷总结篇84.柱状图中最大的矩形 题目链接 这道题和接雨水是两个相似的题&#xff0c;相辅相成的那种&#xff0c;双指针是过不了力扣的会超时&#xff0c;所以我也…

pandas提取键值对(json和非json格式)

&#xff08;欢迎大家关注我的公众号“机器学习面试基地”&#xff0c;之后将在公众号上持续记录本人从非科班转到算法路上的学习心得、笔经面经、心得体会。未来的重点也会主要放在机器学习面试上&#xff01;&#xff09; 最近工作中需要解析一些有模型输入输出信息的csv日志…