手动实现 数组和链表

news2025/7/16 7:06:52

数组和链表示意图

在这里插入图片描述

目的

不用java标准库
自己时间 一个 arraylist 和 linked list

区别

数组

数组 支持 随机访问 可以立即访问
根据 第一个元素的位置, 推算出 第三个地方的位置

如下图所示,假设我们知道 头的位置是X
数组是 int类型
每个位置就是 占4个字节
所以第三个元素的位置应该是 X + 3 x 4
即为 X + 12
就可以直接访问 第三个位置,直接进行赋值操作。

C语言有句话, 数组是指针, 指针不是数组。
我们 可以 把 数组就当做指针
我们知道 指针,即为 第一个元素位置
我们又可以根据 数组的类型 推断出 每个位置的大小
然后 通过 arr + X x 元素大小 直接推算出我们想修改的位置。
在这里插入图片描述

链表

链表存储的元素,它们不是连在一起放在内存的。
而是 分散位于 不同的位置。

通过 next指针记录下一个元素位置是多少,然后找到下一个元素。

只能通过 next指针 一个一个访问。
在这里插入图片描述

但是对于数组来说,每删除一个元素,需要将后面的所有元素都 往前移动1个位置。
在这里插入图片描述
对数组的增加操作,也类似,需要将后面的所有元素都 往后移动1个位置。

对于链表来说,增删都比较方便。

另外,对于数组来说,一开始就设置固定大小空间,当数组满了之后,需要重新申请一块新的空间,更大的
然后 将所有元素 都 移动过去。

数据结构的本质

遍历 和 访问

都是增删查改

postion 和 index的区别

在这里插入图片描述

数组实现

import java.util.NoSuchElementException;

public class MyArrayList<E>{
    // 真正存储的数据
    private E[] data;
    private int size;
    private static final int INIT_CAP = 1;

    public MyArrayList() {this(INIT_CAP);}

    public MyArrayList(int initCapacity) {
        data = (E[])new Object[initCapacity];
    }

    /** 增 **/

    // 在数组尾部添加一个元素 e
    public void addLast(E e) {
        // 边界条件 Boundary conditions
        if (data.length == size) {
            resize(data.length * 2); // 扩容 Expansion
        }
        data[size]= e;
        size++;
    }
    // 在index 索引位置添加一个元素 element
    private void add(int index, E element) {
        checkPositionIndex(index); // 注意这里检查position

        if (data.length == size) {
            resize(data.length * 2); // 扩容 Expansion
        }

        // data[index...] -> data[index+1 ....]
        // 数据迁移 Data migration
        System.arraycopy(data, index, data, index + 1, size - 1);
        // 数据赋值 Data assignment
        data[index] = element;
        size++;
    }



    /** 删 **/

    // 删除数组的最后一个元素 并 返回
    public E removeLast() {
        if (isEmpty()) { // 数组为空
            throw new NoSuchElementException();
        }

        if (size < data.length / 4) { // 缩容 Shrinkage
            resize(data.length / 2);
        }

        E last = data [size - 1];

        // 删除最后一个元素 Delete the last element
        data[size - 1] = null;
        size--;

        return last;
    }

    // 删除index 对应的元素 并返回
    public E remove(int index) {
        checkElementIndex(index);


        if (size < data.length / 4) {
            resize (data.length / 2);
        }

        // 数据迁移
        // data[index + 1....] -> data[index...]
        E delVal = data[index];
        System.arraycopy(data, index + 1, data,  index,size - index - 1);

        // 删除最后一个元素
        data[size - 1] = null;
        size--;
        return delVal;
    }

    /** 查 **/

    // 返回索引 index 对应的元素
    public E get(int index) {
        checkElementIndex(index);
        return data[index];
    }


    /** 改 **/
    // 将索引 index的元素 修改为 element 并返回之前的值
    public E set(int index, E element) {
        checkElementIndex(index);
        E oldVal = data[index];
        data[index] = element;
        return oldVal;
    }

    /** 工具函数 */
    public int size() {
        return size;
    }
    public boolean isEmpty() {
        return size == 0;
    }

    /*** 私有函数*/
    // 明确index 和 postion区别
    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }

    private boolean isPositionIndex(int index) {
        return index >= 0 && index <= size;
    }

    // 检查 index 索引位置是否可以存在元素
    private void checkElementIndex(int index) {
        if (!isElementIndex(index)) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }

    private void checkPositionIndex(int index) {
        if (!isPositionIndex(index)) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }
    private void resize(int newCap) {
        E[] temp = (E[]) new Object[newCap];
        System.arraycopy(data, 0, temp, 0, size);
        data = temp;
    }
}

数组增加元素(add)的图解

再写一遍。逻辑同上面


import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyArrayList<E> implements Iterable<E> {

    // 真正存储数据的底层数组 The underlying array that really stores data
    private E[] data;
    // 记录当前元素个数 Record the current number of elements
    private int size;
    // 默认初始容量 Default initial capacity
    private static final int INIT_CAP = 1;

    public MyArrayList(){
        this(INIT_CAP);
    }
    public MyArrayList(int initCapability) {
        data = (E[])new Object[initCapability];
        size = 0;
    }

    /** 增**/
    public void addLast(E e){
        int cap = data.length;
        if (size == cap) {
            resize(2 * cap);
        }

        data[size] = e;
        size++;
    }
    public void add(int index, E e){
        checkPositionIndex(index);

        int cap = data.length;

        if (size == cap) {
            resize(2 * cap);
        }

        // move dat data[index...] -> data[index + 1..]
        System.arraycopy(data, index, data, index + 1, size - index);

        data[index] = e;

        size++;
    }
    public void addFirst(E e){
        add(0, e);
    }

    /** 删*/
    public E removeLast(){
        if (size == 0) {
            throw new NoSuchElementException();
        }

        int cap = data.length;

        if (size == cap / 4) {
            resize(cap / 2);
        }

        E deletedE = data[size - 1];

        data[size - 1] = null;

        size--;

        return deletedE;
    }
    public E remove(int index){

        checkElementIndex(index);

        int cap = data.length;

        if (size < cap / 4) {
            resize(cap / 2);
        }

        E deletedE = data[index];

        // move data data[index + 1....] -> data[index....]
        System.arraycopy(data, index + 1, data, index, size - index - 1);

        data[size - 1] = null;
        size--;
        return deletedE;
    }
    public E removeFirst(){
        return remove(0);
    }

    /** 查*/
    public E get(int index){
        checkElementIndex(index);

        return data[index];
    }
    /** 改*/
    public E set(int index, E element){
        checkElementIndex(index);

        E old = data[index];
        data[index] = element;

        return old;
    }


    /** tool method functions */
    public int size(){
        return size;
    }

    public boolean isEmpty(){
        return size == 0;
    }

    // 修改容量大小 Modify capacity size
    public void resize(int newCap) {
        if (size > newCap) return;
        E[] temp = (E[])new Object[newCap];
        /** System.arraycopy
         * 四个参数:
         *      param1: the array to copied from
         *      param2: the start index in original
         *      param3: the array to be copied in
         *      param4: the total no of coponments to be copied
         */
        System.arraycopy(data, 0, temp,0 ,size);
        data = temp;
    }
    // Check whether there are elements in the index position
    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }
    // Check whether elements can be added to the index position.
    private boolean isPositionIndex(int index) {
        return index >=0 && index <= size;
    }

    private void checkElementIndex(int index) {
        if (!isElementIndex(index)){
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }
    private void checkPositionIndex(int index) {
        if (!isPositionIndex(index)) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }

    @Override
    public Iterator<E> iterator(){
        return new Iterator<E>() {
            private  int p = 0;
            @Override
            public boolean hasNext() {
                return p != size;
            }

            @Override
            public E next() {
                return data[p++];
            }
        };
    }


    private void display() {
        System.out.println("size = " + size + "cap = " + data.length);
        System.out.println(Arrays.toString(data));
    }


    public static void main(String[] args) {
        // 初始容量设置为 3
        MyArrayList<Integer> arr = new MyArrayList<>(3);

        // 添加 5 个元素
        for (int i = 1; i <= 5; i++) {
            arr.addLast(i);
        }

        arr.remove(3);
        arr.add(1, 9);
        arr.addFirst(100);
        int val = (int)arr.removeLast();

        for (int i = 0; i < arr.size(); i++) {
            System.out.println(arr.get(i));
        }
    }

}

链表

图解
头部添加元素
在这里插入图片描述

尾部插入
在这里插入图片描述
删除元素
在这里插入图片描述

在index对应位置插入元素
在这里插入图片描述
如果要在1的位置插入元素,首先要找到 index为 0 和 index为1的位置,然后 进行操作。
在这里插入图片描述
在这里插入图片描述
双链表实现代码

import java.util.NoSuchElementException;

public class MyLinkedList<E> {
    // 双链表的节点
    private static class Node<E>{
        E val;
        Node<E> next;
        Node<E> prev;
        Node(E val){
            this.val = val;
        }
    }
    private final Node<E> head, tail;
    private int size;

    public MyLinkedList(){
        this.head = new Node<>(null);
        this.tail = new Node<>(null);

        head.next = tail;
        tail.prev = head;

        this.size = 0;
    }

    /**增*/
    public void addFirst(E e){
        Node<E> node = new Node<>(e);
        Node<E> temp = head.next;

        // head 和 temp
        node.prev = head;
        node.next = temp;

        head.next = node;
        temp.prev = node;
        size++;
    }
    public void addLast(E e){
        Node<E> node = new Node<>(e);
        Node<E> temp = tail.prev;
        // temp head
        node.next = tail;
        node.prev = temp;

        tail.prev = node;
        temp.next = node;

        size++;
    }
    public void add(int index, E e){
        checkPositionindex(index);

        Node<E> node = new Node<>(e);

        Node<E> p = getNode(index);
        Node<E> temp = p.prev;

        node.next = p;
        node.prev = temp;

        p.prev = node;
        temp.next = node;

        size++;
    }
    /**删*/
    public E removeFirst(){
        if (isEmpty()) {
            throw new NoSuchElementException();
        }

        Node<E> x = head.next;
        Node<E> temp = x.next;
        // head -> x -> temp
        head.next = temp;
        temp.prev = head;

        x.next = x.prev = null;
        size--;

        return x.val;
    }
    public E removeLast(){
        if (isEmpty()) {
            throw new NoSuchElementException();
        }

        Node<E> x = tail.prev;
        Node<E> temp = x.prev;
        // temp <-> x <-> tail
        temp.next = tail;
        tail.prev = temp;

        x.prev = x.next = null;

        size--;
        return x.val;
    }
    public E remove(int index){
        checkElementIndex(index);

        Node<E> p = getNode(index);
        Node<E> prev = p.prev;
        Node<E> next = p.next;
        // prev <-> p <next>;

        prev.next = next;
        next.prev = prev;

        p.next = p.prev = null;
        size--;

        return p.val;
    }
    /**查*/
    public E getFirst(){
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        return head.next.val;
    }
    public E getLast(){
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        return tail.prev.val;
    }
    public E get(int index){
        checkElementIndex(index);
        Node<E> p = getNode(index);
        return p.val;
    }
    /**改*/
    public E set(int index, E element){
        checkElementIndex(index);
        Node<E> p = getNode(index);
        E old = p.val;
        p.val = element;
        return old;
    }




    /** other utility funcations 工具函数*/
    public int size(){
        return this.size;
    }

    public boolean isEmpty(){
        return 0 == size;
    }

    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }

    private boolean isPositionIndex(int index) {
        return index >=0 && index <= size;
    }

    // 检查index索引位置是否可以存在元素
    // Check whether the element can exist at the index position
    private void checkElementIndex(int index) {
        if (isElementIndex(index)) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }

    private void checkPositionindex(int index) {
        if (isPositionIndex(index)) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }

    private Node<E> getNode(int index) {
        checkElementIndex(index);

        Node<E> p = head.next;
        for (int i = 0; i < index; i++) {
            p = p.next;
        }
        return p;
    }
}

单链表实现

import java.util.NoSuchElementException;

public class MyLinkedList<E> {
    private static class Node<E> {
        E val;
        Node<E> next;

        Node(E val) {
            this.val = val;
        }
    }

    private final Node<E> head, tail;
    private int size;

    public MyLinkedList(){
        this.head = new Node<E>(null);
        this.tail = new Node<E>(null);

        head.next = tail;
        this.size = 0;
    }


    /**增*/
    public void addFirst(E e){
        Node<E> x = new Node<>(e);
        Node<E> temp = head.next;
        // head -> temp
        // x-> temp
        x.next = temp;
        // head-> x -> temp
        head.next = x;
        size++;
    }
    public void addLast(E e){
        Node<E> x = new Node<>(e);
        Node<E> temp;

        // find the node before last node
        if (size > 0) {
            temp = getNode(size - 1);
        } else {
            temp = head;
        }

        // x-> tail
        x.next = tail;
        // temp -> x -> tail
        temp.next = x;
        size++;
    }
    public void add(int index, E e){
        checkPositionIndex(index);
        if (index == size) {
            addLast(e);
            return;
        }

        Node<E> x = new Node<>(e);
        Node<E> temp;
        if (index >= 0) {
            temp = getNode(index - 1);
        } else {
            temp = head;
        }

        Node<E> p = getNode(index);

        // x->p
        x.next = p;
        // temp -> x -> p
        temp.next = x;

        size++;
    }
    /**删*/
    public E removeFirst(){
        if (isEmpty()){
            throw new NoSuchElementException();
        }

        Node<E> x = head.next;
        head.next = head.next.next;

        x.next = null;
        size--;
        return x.val;
    }
    public E removeLast(){
        if (isEmpty()){
            throw new NoSuchElementException();
        }

        Node<E> p = getNode(size - 1);
        Node<E> temp;
        if (size >= 2) {
            temp = getNode(size - 2);
        } else {
            temp = head;
        }

        // temp -> x -> tail
        temp.next = tail;
        p.next = null;
        size--;

        return p.val;
    }
    public E remove(int index){
        checkElementIndex(index);
        Node<E> p = getNode(index);
        Node<E> prev;

        if (index >= 0) {
            prev = getNode(index - 1);
        } else {
            prev = head;
        }

        // prev -> p -> next
        Node<E> next = p.next;
        prev.next = next;

        p.next = null;
        size--;
        return next.val;
    }
    /**查*/
    public E getFirst(){
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        return head.next.val;
    }
    public E getLast(){
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        return getNode(size - 1).val;
    }
    public E get(int index){
        checkElementIndex(index);
        Node<E> p = getNode(index);
        return p.val;
    }
    /**改*/
    public E set(int index, E element){
        checkElementIndex(index);
        Node<E> p = getNode(index);

        E old = p.val;
        p.val = element;
        return old;
    }

    /**其他工具函数Other tool functions*/
    public int size(){
        return this.size;
    }
    public boolean isEmpty(){
        return this.size == 0;
    }
    public  boolean isElementIndex(int index){
        return index >= 0 && index < size;
    }
    public boolean isPositionIndex(int index){
        return index >= 0 && index <= size;
    }
    private void checkElementIndex(int index){
        if (isElementIndex(index)) {
            throw new IndexOutOfBoundsException("index: "+ index + ", size:" + size);
        }
    }

    private void checkPositionIndex(int index){
        if (isPositionIndex(index)) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }

    private Node<E> getNode(int index){
        checkElementIndex(index);
        Node<E> p = head.next;
        for (int i = 0; i < index; i++) {
            p = p.next;
        }

        return p;
    }

}

Leetcode练习题

易错点 注意 add(index) 和 delete(index)的两者不同
前者检查的是position
后者检查的是index

https://leetcode.com/problems/design-linked-list

class ListNode {
    int val;
    ListNode prev, next;
    public ListNode(int val){
        this.val = val;
    }
}
class MyLinkedList {
    private final ListNode head, tail;
    int size;
    public MyLinkedList(){
        this.head = new ListNode(-1);
        this.tail = new ListNode(-1);
        head.next = tail;
        tail.prev = head;
        this.size = 0;
    }
    
    public int get(int index) {
        if (!checkIndex(index)) return -1;
        ListNode p = head.next;
        for (int i = 0; i < index; i++) {
            p = p.next;
        }
        return p.val;
    }
    
    public void addAtHead(int val) {
        ListNode x = new ListNode(val);
        ListNode temp = head.next;

        x.prev = head;
        x.next = temp;

        head.next = x;
        temp.prev = x;

        this.size++;
    }   
    
    public void addAtTail(int val) {
        ListNode x = new ListNode(val);
        ListNode temp = tail.prev;

        x.next = tail;
        x.prev = temp;

        temp.next = x;
        tail.prev = x;

        this.size++;
    }
    
    public void addAtIndex(int index, int val) {
        if (!checkPostion(index)) return;

        ListNode x = new ListNode(val);

        ListNode p = getNode(index);
        ListNode temp = p.prev;

        x.prev = temp;
        x.next = p;

        temp.next = x;
        p.prev = x;

        this.size++;
    }
    
    public void deleteAtIndex(int index) {
        if (!checkIndex(index)) return;

        ListNode p = getNode(index);
        ListNode prev = p.prev;
        ListNode next = p.next;

        prev.next = next;
        next.prev = prev;

        p.next = p.prev = null;

        this.size--;
    }

    private boolean checkIndex(int index) {
        return index >= 0 && index < size;
    }

    private boolean checkPostion(int index) {
        return index >= 0 && index <= size;
    }

    private ListNode getNode(int index) {
        ListNode p = head.next;
        for (int i = 0; i < index; i++) {
            p = p.next;
        }        
        return p;
    }
}

Reference

https://appktavsiei5995.pc.xiaoe-tech.com/p/t_pc/course_pc_detail/video/v_62655468e4b09dda125fa007?product_id=p_626541bbe4b0812e1790e3f8&content_app_id=&type=6

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

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

相关文章

Qt音视频开发21-mpv内核万能属性机制

一、前言 搞过vlc内核后又顺带搞了搞mpv内核&#xff0c;mpv相比vlc&#xff0c;在文件数量、sdk开发便捷性方面绝对占优势的&#xff0c;单文件&#xff08;可能是静态编译&#xff09;&#xff0c;不像vlc带了一堆插件&#xff0c;通过各种属性来set和get值&#xff0c;后面…

第十四届蓝桥杯三月真题刷题训练——第 5 天

目录 题目1&#xff1a;数的分解 题目描述 运行限制 代码&#xff1a; 题目2&#xff1a;猜生日 题目描述 运行限制 代码&#xff1a; 题目3&#xff1a;成绩分析 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码&#xff1a; 题目4&#xff1a;最大和…

Vue3做出B站【bilibili】 Vue3+TypeScript【快速入门一篇文章精通系列(一)前端项目案例】

本项目分为二部分 1、后台管理系统&#xff08;用户管理&#xff0c;角色管理&#xff0c;视频管理等&#xff09; 2、客户端&#xff08;登录注册、发布视频&#xff09; Vue3做出B站【bilibili】 Vue3TypeScript【快速入门一篇文章精通系列&#xff08;一&#xff09;前端项目…

vue3 拖拽 穿梭框

文章目录期望结果当前技术栈实现方法安装 sortablejs导入 sortablejs视图 通过 id 绑定 sortablejs 数据通过 data-xxx 自定义属性 挂载ts中 通过id获取dom 实现拖拽 getNewArr函数通过自定义属性对数据做处理以下是全部代码官网链接下面是文档UsageOptionsgroup optionsort op…

代码随想录之哈希表(力扣题号)

242. 有效的字母异位词 直接用数组模拟哈希表 只有小写字母&#xff0c;开26的数组就可以了 class Solution {public boolean isAnagram(String s, String t) {//24-28int[] hash new int[26];Arrays.fill(hash,0);for(int i0;i<s.length();i){hash[s.charAt(i)-a];}for(i…

2023年3月全国数据治理工程师认证DAMA-CDGA/CDGP火热报名中...

弘博创新是DAMA中国授权的数据治理人才培养基地&#xff0c;贴合市场需求定制教学体系&#xff0c;采用行业资深名师授课&#xff0c;理论与实践案例相结合&#xff0c;快速全面提升个人/企业数据治理专业知识与实践经验&#xff0c;通过考试还能获得数据专业领域证书。 DAMA认…

【致敬女神】HTMLReport应用之Unittest+Python+Selenium+HTMLReport项目自动化测试实战

HTMLReport应用之UnittestPythonSeleniumHTMLReport项目自动化测试实战1 测试框架结构2 技术栈3 实现思路3.1 使用HtmlTestRunner3.2 使用HTMLReport4 TestRunner参数说明4.1 源码4.2 参数说明5 框架代码5.1 common/reportOut.py5.2 common/sendMain.py5.3 report5.3.1 xxx.htm…

ARM架构下使用Docker安装Nacos

大家好&#xff0c;我是中国码农摘星人。 欢迎分享/收藏/赞/在看&#xff01; 注意&#xff1a;以下内容仅适用于 ARM 架构&#xff0c;X86 及 AMD 架构理论类似&#xff0c;只需要修改配置即可。 构建 MySQL 8.x 镜像 MySQL 5.x 版本没有 ARM 架构的镜像 FROM mysql:8.0.32 A…

Java 8 排序

今天分享 Java 8 进行排序的 10 个姿势&#xff0c;其实就是把 Java 8 中的 Lambda、Stream、方法引用等知识点串起来 传统排序 现在有一个 List 集合&#xff1a; public static List<User> LIST new ArrayList() {{add(new User("Lisa", 23));add(new Us…

三维人脸实践:基于Face3D的渲染、生成与重构

face3d: Python tools for processing 3D face git code: https://github.com/yfeng95/face3d paper list: PaperWithCode 该方法广泛用于基于三维人脸关键点的人脸生成、属性检测&#xff08;如位姿、深度、PNCC等&#xff09;&#xff0c;能够快速实现人脸建模与渲染。推荐…

如何判断多账号是同一个人?用图技术搞定 ID Mapping

原文出处&#xff1a;https://discuss.nebula-graph.com.cn/t/topic/11873 本文是一个基于图数据库 NebulaGraph 上的图算法、图数据库、图神经网络的 ID-Mapping 方法综述&#xff0c;除了基本方法思想的介绍之外&#xff0c;我还给大家弄了可以跑的 Playground。 基于图数据…

浏览器:浏览器指纹

一、引子 场景一、绑定用户与浏览器&#xff08;设备&#xff09;&#xff0c;比如某一个网站的账号给到用户&#xff0c;用户只能在自己的电脑的某浏览器使用。 场景二、精准推送广告。 场景三、公司做营销活动&#xff0c;防止活动奖品被程序薅羊毛。 等等场景我们有什么…

Qt配置VS的编译环境(以MSVC2015 64bit为例)

目录 一、原因 二、VS2015安装 三、配置套件&#xff08;Kits&#xff09; 一、原因 很多时候&#xff0c;由于VS版本切换&#xff0c;需要从高版本切换到低版本&#xff0c;或者从低版本升级到高版本&#xff0c;例如VS2019到VS2015&#xff0c;或者VS2010到VS2015。 以VS2…

辽宁千圣文化:抖音店铺怎么做二次优化?

抖音商品卡订单是指永华在抖音、抖音极速版&#xff0c;通过直播的方式出现短视频页面商品卡之后&#xff0c;直接成交商品详情页直接成交后的订单&#xff0c;那么跟着辽宁千圣文化小编来一起看看吧&#xff01;一.与政策有关1.什么是「商品卡订单」&#xff1f;用户通过抖音、…

FCN网络(Fully Convolutional Networks)

首个端到端的针对像素级预测的全卷积网络 原理&#xff1a;将图片进行多次卷积下采样得到chanel为21的特征层&#xff0c;再经过上采样得到和原图一样大的图片&#xff0c;最后经过softmax得到类别概率值 将全连接层全部变成卷积层&#xff1a;通常的图像分类网络最后几层是全…

六、死信队列

1、死信的概念 2、死信来源 3、死信实战 3.1 代码架构 正常队列绑定正常交换机正常队列绑定死信交换机死信队列绑定死信 3.2 消息TTL过期变成死信 生产者向 normal_exchange发送消息&#xff0c;通过路由键zhangsan路由到 normal-queue中&#xff0c;消息设置TTL属性 /**…

【自监督论文阅读笔记】What Makes for Good Views for Contrastive Learning?

Abstract 数据的多个视图之间的对比学习最近在自监督表示学习领域取得了最先进的性能。尽管取得了成功&#xff0c;但对不同视角选择的影响研究较少。在本文中&#xff0c;我们使用理论和实证分析来 更好地理解视图选择的重要性&#xff0c;并认为我们应该减少视图之间的互信息…

三分钟完成Stable Diffusion本地安装(零基础体验AI绘画)

三分钟完成Stable Diffusion本地安装前言安装步骤下载链接前言 最近AI绘画很火&#xff0c;很多无编程基础的小伙伴也想体验一下&#xff0c;所以写这篇博客来帮助小伙伴们愉快的体验一下~废话少说&#xff0c;我们直接开整&#xff01; 安装步骤 首先&#xff0c;下载本项目的…

电脑启动后显示器黑屏怎么办?排查下面4个问题,快速解决

电脑启动出现显示器黑屏是一个相当常见的问题。如果您遇到了这个问题&#xff0c;不要惊慌&#xff0c;因为它有很多可能的原因&#xff0c;可以采取一些简单的措施来解决它。在本文中&#xff0c;小编将介绍下面4种常见的电脑启动后显示器黑屏的原因&#xff0c;排查这些原因&…

合并两个有序链表(精美图示详解哦)

全文目录引言合并两个有序链表题目描述方法一&#xff1a;将第二个链表合并到第一个思路实现方法二&#xff1a;尾插到哨兵位的头节点思路实现总结引言 在前面两篇文章中&#xff0c;我们介绍了几道链表的习题&#xff1a;反转链表、链表的中间结点、链表的倒数第k个结点&…