JavaDS4-链表

news2025/1/15 15:52:56

目录

1.定义

2.结构

2.1.类似火车

2.2.分类

2.2.1.按方向分

2.2.2.按是否带头节点分

2.2.3.按是否循环分

3.重点掌握

3.1.无头单向非循环链表

3.1.1.在链表的头部添加节点

3.1.2.在链表的任意位置index处添加节点

3.1.3.在链表的尾部添加节点

3.1.4.查询链表的任意位置index处的节点值

3.1.5.判断链表中是否包含值为data的节点

3.1.6.修改链表中任意位置index处的节点值,返回修改前的节点值

3.1.7.删除链表的头节点

3.1.8.删除链表中任意位置index处节点

3.1.9.删除链表中第一次出现某个值的节点

3.1.10.删除链表中值为data的所有节点

3.1.11.判断链表的index是否合法

3.1.12.toString()方法

3.2.带头单向非循环链表

3.2.1.在链表任意位置index处插入节点

3.2.2.在链表头部添加节点

3.2.3.在链表尾部添加节点

3.2.4.在链表任意位置index处删除节点

3.2.5.删除链表头部节点

3.2.6.删除链表尾部节点

3.2.7.toString()方法

3.3.无头双向链表

3.3.1.在链表的头部添加节点

3.3.2.在链表的尾部添加节点

3.3.3.在链表的任意位置index处添加节点

3.3.4.查询链表的任意位置index处的节点值

3.3.5.修改链表中任意位置index处的节点值

3.3.6.传入一个双向链表节点,将该节点从双向链表中删除

3.3.7.删除链表中第一次出现某个值的节点

3.3.8.删除链表中值为val的所有节点

3.3.9.判断链表的index是否合法

3.3.10.根据index与size的大小关系快速定位指定index位置的节点

3.3.11.toString()方法

1.定义

链表是一种物理存储结构上非连续的存储结构,数据元素的逻辑顺序是通过链表中的引用连接次序来实现的。

2.结构

2.1.类似火车

(在Java中一切皆对象)分为车厢类和火车类。

特点:

车厢之间为逻辑先后关系(车厢1在车厢2之前),物理上不连续(中间有钩子相连)。

火车可以根据人员多少来方便地增加/减少车厢。

2.2.分类

2.2.1.按方向分

a.单向链表:只能从头到尾,不能从后向前。

b.双向链表:既能从头到尾,也能从后向前。

2.2.2.按是否带头节点分

a.不带头节点的单链表:

b.带头节点的单链表:

2.2.3.按是否循环分

a.非循环单链表:

b.循环单链表:

3.重点掌握

3.1.无头单向非循环链表

a.结构简单,一般不会单独用来存储数据,更多是作为其他数据结构的子结构,如哈希桶(盛放不同key链表的容器),图的邻接表等。

b.笔试,面试中很多。

3.1.1.在链表的头部添加节点

3.1.2.在链表的任意位置index处添加节点

3.1.3.在链表的尾部添加节点

3.1.4.查询链表的任意位置index处的节点值

3.1.5.判断链表中是否包含值为data的节点

3.1.6.修改链表中任意位置index处的节点值,返回修改前的节点值

3.1.7.删除链表的头节点

3.1.8.删除链表中任意位置index处节点

3.1.9.删除链表中第一次出现某个值的节点

3.1.10.删除链表中值为data的所有节点

3.1.11.判断链表的index是否合法

3.1.12.toString()方法

//车厢类
class Node{
    //存储具体元素
    int data;
    //存储下一个节点的地址
    Node next; //next是自定义的Node引用类型,存储Node类型的对象的地址,即车厢地址

    //构造方法
    public Node(int data){
        this.data = data;
    }

    public Node(int data, Node next){
        this.data = data;
        this.next = next;
    }
}

//火车类 实际上是多个车厢的组合
//单链表只能从前往后遍历
public class SingleLinkedList {
    //当前火车中车厢的个数(实际存储的元素的个数)
    private int size;
    //当前火车的第一个节点
    private Node head;

    /**
     * 在链表的头部添加元素
     * @param data
     */
    public void addFirst(int data){
        //判断当前火车是否为空
        //一个节点都没有,要插入的节点就是第一个节点
        if(size == 0){
            Node node = new Node(data); //引用数据类型,存地址
            head = node;
            size++;
        }else{
            //当前火车已经存在节点了
            Node node = new Node(data);
            node.next = head;
            head = node;
            size++;
        }
    }

    /**
     * 在链表的任意位置index处添加元素
     * @param index
     * @param data
     */
    public void addIndex(int index, int data){
        //判断边界条件,注意合法性
        if(index < 0 || index > size){
            System.err.println("add index illegal!");
            return;
        }

        //若index == 0,此时不需要找前驱节点(无前驱节点),可将此作为边界条件
        if(index == 0){
            //头插
            addFirst(data);
            return;
        }

        //说明此时index合法且在中间位置(包含最后节点)
        //此时需要找到待插入位置index的前驱节点(单链表只能从前向后遍历)
        Node node = new Node(data);
        Node prev = head;
        for (int i = 0; i < index - 1; i++) {
            prev = prev.next;
        }
        //prev引用指向当前插入index的前驱节点(prev引用从头走了index - 1步,此时prev指向index - 1节点)
        node.next = prev.next;
        prev.next = node;
        size++;
    }

    /**
     * 在链表的尾部添加元素
     * @param data
     */
    public void addLast(int data){
        addIndex(size, data);
    }

    /**
     * 查询链表index处的节点数据值
     * @param index
     * @return
     */
    public int get(int index){
        if(rangeCheck(index)){
            Node node = head;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
            //此时node指向待查找节点的索引
            int data = node.data;
            return data;
        }else{
            System.err.println("get index illegal!");
            return -1;
        }
    }

    /**
     * 判断链表中是否包含节点值为data的节点
     * @param data
     * @return
     */
    public boolean contains(int data){
        Node node = head;
        while(node != null){
            if(node.data == data){
                System.out.println("找到元素");
                return true;
            }
            node = node.next;
        }
        System.out.println("没有找到该元素");
        return false;
    }

    /**
     * 修改单链表中index位置的元素,返回修改前的元素值
     * @param index
     * @param data
     * @return
     */
    public int set(int index, int data){
        if(rangeCheck(index)){
            Node node = head;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
            //此时走到index处
            int oldData = node.data;
            node.data = data;
            return oldData;
        }else{
            System.err.println("set index illegal!");
            return -1;
        }
    }

    /**
     * 删除单链表头节点
     */
    public void removeFirst(){
        //判断边界条件
        if(head == null || head.next == null){
            //删除完链表为空链表
            return;
        }
        Node node = head;
        head = head.next;
        node.next = null;
        size--;
    }

    /**
     * 删除单链表中任意位置index处的元素
     * @param index
     */
    public void removeIndex(int index){
        if(rangeCheck(index)){
            if(index == 0){
                //删除头节点
                removeFirst();
            }else{
                //删除中间位置节点
                Node prev = head;
                for (int i = 0; i < index - 1; i++) {
                    prev = prev.next;
                }
                //此时prev指向待删除节点的前驱节点
                //node就是待删除的节点
                Node node = prev.next;
                //连接前驱节点和后继节点
                prev.next = node.next;
                //当前节点的next引用置为空,脱钩操作
                node.next = null;
                size--;
            }
        }else{
            System.err.println("remove index illegal!");
        }
    }

    /**
     * 删除单链表中第一次出现某个值的元素
     * @param data
     */
    public void removeValueOnce(int data){
        //先找到待删除元素的节点
        //先判断头节点的情况
        if(head.data == data){
            //此时头节点就是第一个待删除的节点
            removeFirst();
        }else{
            //此时头节点一定不是要删除的节点
            //从头节点开始找到待删除元素的节点前驱
            Node prev = head;
            //此时要看下一个节点的情况
            while(prev.next != null){
                //找到待删除的节点
                if(prev.next.data == data){
                    //此时prev就是待删除节点的前驱
                    //node就是待删除的节点
                    Node node = prev.next;
                    //将prev跳过当前node
                    prev.next = node.next;
                    node.next = null;
                    size--;
                    break;
                }else{
                    //此时prev的下一个节点不是待删除节点
                    //继续向下一个节点寻找
                    prev = prev.next;
                }
            }
        }
    }

    /**
     * 删除单链表中值为data的所有元素
     * @param data
     */
    public void removeAllValue(int data){
        //判断头节点的情况
        //头节点以及之后出现了多个连续的待删除的节点
        while(head != null && head.data == data){
            Node node = head;
            head = head.next;
            node.next = null;
            size--;
        }
        //此时head一定不是待删除的节点
        //head.data != data;
        if(head == null){
            //此时链表全是待删除的元素节点,已删除完毕
            return;
        }else{
            //此时头节点已经处理完毕,并且链表也不为空,向下一个节点开始进行判断
            Node prev = head;
            while(prev.next != null){
                if(prev.next.data == data){
                    Node node = prev.next;
                    prev.next = node.next;
                    node.next = null;
                    size--;
                    //当处理完当前删除节点后,要继续判断下一个节点是否也要删,此时prev不能移动
                }else{
                    //此时prev的下一个节点不是要删除的节点,prev继续向后走一个单位
                    prev = prev.next;
                }
            }
        }
    }

    public String toString(){
        String ret = " ";
        //此处有一个临时变量node来存储head的值,保护head,防止遍历完head不见了,这个链表就不能用了
        Node node = head;
        while(node != null){
            ret += node.data + "->";
            //继续访问下一个车厢
            node = node.next;
        }
        ret += "NULL";
        return ret;
    }

    /**
     * 判断index是否合法
     * @param index
     * @return
     */
    private boolean rangeCheck(int index){
        if(index < 0 || index >= size){
            return false;
        }
        return true;
    }

    //测试
    public static void main(String[] args) {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.addFirst(3); //3->NULL
        singleLinkedList.addFirst(2); //2->3->NULL
        singleLinkedList.addFirst(1); //1->2->3->NULL
        singleLinkedList.addLast(7); //1->2->3->7->NULL
        singleLinkedList.addIndex(2,2); //1->2->2->3->7->NULL
        System.out.println(singleLinkedList); //1->2->2->3->7->NULL

        System.out.println(singleLinkedList.get(3)); //3

        System.out.println(singleLinkedList.contains(11)); //false

        System.out.println(singleLinkedList.set(2, 9)); //2

        System.out.println(singleLinkedList); //1->2->9->3->7->NULL

        singleLinkedList.removeFirst(); //2->9->3->7->NULL
        singleLinkedList.removeIndex(1); //2->3->7->NULL
        singleLinkedList.addLast(2); //2->3->7->2->NULL
        singleLinkedList.removeAllValue(2); //3->7->NULL

        System.out.println(singleLinkedList); //3->7->NULL
    }
}

3.2.带头单向非循环链表

3.2.1.在链表任意位置index处插入节点

3.2.2.在链表头部添加节点

3.2.3.在链表尾部添加节点

3.2.4.在链表任意位置index处删除节点

3.2.5.删除链表头部节点

3.2.6.删除链表尾部节点

3.2.7.toString()方法

public class SingleLinkedListWithHead {
    //虚拟头节点 在内存中实实在在存在的节点,有一个引用指向
    private Node dummyHead = new Node(-1);
    //只声明一个Node类的引用,无具体节点,在内存中没有开空间 private Node dummyHead;
    //-1表示这个节点的data值无意义,这个节点就是来连接/脱钩其他节点的
    //data若不赋值,int默认值为0,有时这个0确实是需要存储的元素,负数还是很少见

    //单链表中具体节点的个数(不包括虚拟头节点)
    private int size;

    /**
     * 在任意位置index处插入一个元素
     * @param index
     * @param data
     */
    public void addIndex(int index, int data){
        if(index < 0 || index > size){
            System.err.println("add index illegal!");
            return;
        }
        //此时index无论为何值,都存在前驱节点
        Node prev = dummyHead;
        for (int i = 0; i < index; i++) {
            prev =prev.next;
        }
        //prev就指向了待插入的前驱节点
        Node node = new Node(data);
        node.next = prev.next;
        prev.next = node;
        size++;
    }

    /**
     * 头插
     * @param data
     */
    public void addFirst(int data){
        addIndex(0, data);
    }

    /**
     * 尾插
     * @param data
     */
    public void addLast(int data){
        addIndex(size, data);
    }

    public String toString(){
        String ret = " ";
        Node node = dummyHead.next;
        while(node != null){
            ret += node.data + "->";
            node = node.next;
        }
        ret += "NULL";
        return ret;
    }

    /**
     * 在任意位置删除节点
     * @param index
     * @return
     */
    public int removeIndex(int index){
        if(index < 0 || index >= size){
            System.err.println("remove index illegal!");
            return -1;
        }
        Node prev = dummyHead;
        //先找到待删除节点的前驱
        for (int i = 0; i < index; i++) {
            prev = prev.next;
        }
        //prev就指向了待删除节点的前驱节点
        Node node = prev.next;
        prev.next = node.next;
        node.next = null;
        size--;
        return node.data;
    }

    /**
     * 删除头节点
     * @return
     */
    public int removeFirst(){
        return removeIndex(0);
    }

    /**
     * 删除尾节点
     * @return
     */
    public int removeLast(){
        return removeIndex(size - 1);
    }
}

3.3.无头双向链表

是Java的集合框架中LinkedList底层实现。

3.3.1.在链表的头部添加节点

3.3.2.在链表的尾部添加节点

3.3.3.在链表的任意位置index处添加节点

3.3.4.查询链表的任意位置index处的节点值

3.3.5.修改链表中任意位置index处的节点值

3.3.6.传入一个双向链表节点,将该节点从双向链表中删除

3.3.7.删除链表中第一次出现某个值的节点

3.3.8.删除链表中值为val的所有节点

3.3.9.判断链表的index是否合法

3.3.10.根据index与size的大小关系快速定位指定index位置的节点

3.3.11.toString()方法

/**
 * 车厢类
 */
class DoubleNode{
    //指向前驱节点
    DoubleNode prev;
    //存储的具体元素
    int val;
    //指向后继节点
    DoubleNode next;

    //构造方法
    public DoubleNode(int val){
        this.val = val;
    }
}

/**
 * 基于int的双向链表
 */
public class DoubleLinkedList {
    //存储的具体车厢个数
    private int size;
    //头节点
    private DoubleNode first;
    //尾节点
    private DoubleNode last;

    /**
     * 头插
     * @param val
     */
    public void addFirst(int val){
        //引入一个局部变量,暂时存储一下头节点的地址
        DoubleNode f = first;//目的是为了判断链表是否为空,不为空时,执行first = node;防止first丢失。
        //要插入一个节点,首先要new一个节点
        DoubleNode node = new DoubleNode(val);
        first = node;//因为是头插,那么这行代码不管当前链表是否为空都会执行
        //若链表为空,则新建的节点既是头节点又是尾节点
        if(f == null){
            last = node;
        }else{
            node.next = f;
            f.prev = node;
        }
        size++;
    }

    /**
     * 尾插
     * @param val
     */
    public void addLast(int val){
        //暂存尾节点地址
        DoubleNode l = last;
        DoubleNode node = new DoubleNode(val);
        last = node;
        if(l == null){
            //链表为空
            first = node;
        }else{
            node.prev = l;
            l.next = node;
        }
        size++;
    }

    /**
     * 在任意位置index处添加元素
     * @param index
     * @param val
     */
    public void addIndex(int index, int val){
        //判断index的合法性
        if(index < 0 || index > size){
            System.err.println("add index illegal!");
            return;
        }else if(index == 0){
            addFirst(val);
        }else if(index == size){
            addLast(val);
        }else{
            //此时0 < index < size
            DoubleNode node = node(index);
            //指向当前位置的前驱节点
            DoubleNode prev = node.prev;
            //要插入的新节点
            DoubleNode newNode = new DoubleNode(val);
            //先处理后半部分引用链
            newNode.next = node;
            node.prev = newNode;
            //再处理前半部分引用链
            prev.next = newNode;
            newNode.prev = prev;
            size++;
        }
    }

    /**
     * 根据index索引取得节点值
     * @param index
     * @return
     */
    public int get(int index){
        if(rangeCheck(index)){
            DoubleNode node = node(index);
            return node.val;
        }else{
            System.err.println("get index illegal!");
            return -1;
        }
    }

    /**
     * 重置index处的值,由index索引修改值
     * @param index
     * @param newVal
     */
    public void set(int index, int newVal){
        if(rangeCheck(index)){
            DoubleNode node = node(index);
            node.val = newVal;
        }else{
            System.err.println("set index illegal!");
        }
    }

    /**
     * 删除第一个出现的元素
     * @param val
     */
    public void removeValueOnce(int val){
        //只需要从头开始遍历
        for (DoubleNode x = first; x != null; x = x.next) {
            if(x.val == val){
                //此时x节点就是待删除的节点
                unlinkNode(x);
                return;
            }
        }
    }

    /**
     * 删除指定的所有元素节点
     * @param val
     */
    public void removeAllValue(int val){
        for (DoubleNode x = first; x != null;) {
            if(x.val == val){
                //x就是待删除的元素
                //先暂存一下next的节点地址
                DoubleNode next = x.next;
                unlinkNode(x);
                x = next;
            }else{
                x = x.next;
            }
        }
    }

    /**
     * 传入一个双向链表节点,将该节点从双向链表中删除
     * 核心思想:分治,先处理前驱或后继,再处理另一半的情况
     * @param node
     */
    private void unlinkNode(DoubleNode node) {
        //待删除节点的前驱
        DoubleNode prev = node.prev;
        //待删除节点的后继
        DoubleNode next = node.next;
        //先处理前半部分引用链
        //边界判断
        if(prev == null){
            first = next;
        }else{
            //此时前驱节点不为空
            prev.next = next;
            node.prev = null;
        }
        //再处理后半部分引用链
        if(next == null){
            last = prev;
        }else{
            //此时后继节点不为空
            next.prev = prev;
            node.next = null;
        }
        size--;
    }

    /**
     * 判断index是否合法
     * @param index
     * @return
     */
    private boolean rangeCheck(int index){
        if(index < 0 || index >= size){
            return false;
        }
        return true;
    }

    /**
     * 根据index与size的大小关系快速定位指定index位置的节点
     * @param index
     * @return
     */
    private DoubleNode node(int index) {
        //根据index与size的大小关系来判断到底是从头向后走还是从后向前走
        if(index < size >> 1){
            //从头向后
            DoubleNode node = first;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
            return node;
        }else{
            //此时index > size >> 1
            //从后向前
            DoubleNode node = last;
            for (int i = size - 1; i > index; i--) {
                node = node.prev;
            }
            return node;
        }
    }

    public String toString(){
        String ret = " ";
        DoubleNode node = first;
        while(node != null){
            ret += node.val + "->";
            node = node.next;
        }
        ret += "NULL";
        return ret;
    }

    //测试
    public static void main(String[] args) {
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
        doubleLinkedList.addLast(2);
        doubleLinkedList.addLast(2);
        doubleLinkedList.addFirst(3);
        System.out.println(doubleLinkedList); //3->2->2->NULL
        doubleLinkedList.removeAllValue(2);
        System.out.println(doubleLinkedList);//3->NULL
    }
}

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

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

相关文章

如何使用单总线?

如何使用单总线&#xff1f;一、什么叫单总线&#xff1f;二、单总线协议&#xff1f;三、怎么使用单总线来做开发&#xff1f;IBUTTON 钥匙读取复制设备项目一、什么叫单总线&#xff1f; 1.如下图&#xff0c;使用单总线的传感器DS18B20 2.使用单总线的储物柜钥匙 3.定义&…

元素偏移量 offset、元素可视区 client和元素滚动 scroll

1、元素偏移量 offset 系列 1.1、offset 概述 offset 翻译过来就是偏移量&#xff0c; 我们使用 offset系列相关属性可以动态的得到该元素的位置&#xff08;偏移&#xff09;、大小等。 获得元素距离带有定位父元素的位置获得元素自身的大小&#xff08;宽度高度&#xff09…

【java】static关键字

static可以修饰的内容如下&#xff1a; ● 变量 ● 方法 ● 代码块 ● 内部类 那就有一个问题&#xff0c;为什么static不能修饰外部类&#xff1f; 我们首先看一下static的作用是什么&#xff1f; 先看看其他人怎么解释的&#xff1a; A static method can be accessed with…

RK3588平台开发系列讲解(进程篇)进程的简介

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、进程的四要素二、进程的三种状态三、task_struct数据结构四、进程优先级五、进程系统调用沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍进程的相关知识。 一、进程的四要素 1、有一段程序供其…

Axure 原型适应到不同平台的方法

“老师&#xff0c;公司要求我做一个不同机型的原型&#xff0c;不想重新做&#xff0c;可以适配吗&#xff1f;” “老师&#xff0c;手机有那么多类型&#xff0c;我难道要做那么多的原型吗&#xff1f;” “老师&#xff0c;axure中怎么进行原型的适配呢&#xff1f;应该怎…

云服务器搭建网站(初学)

第一步&#xff1a;来到/var/www/目录下 第二步&#xff1a;在www目录下创建web1文件夹 第三步&#xff1a;来到root目录 第四步&#xff1a;在root目录上传所需要的压缩包 第五步&#xff1a;解压刚刚上传的压缩包到指定的目录&#xff08;我们刚刚所创建的web1目录&#xff…

HTML5 文件操作

文章目录HTML5 文件操作file元素选择单个文件选择多个文件美化file元素File对象获取文件信息转化单位FileReader对象读取txt文本在线预览图片拖拽文件并读取拖拽图片并预览Blob对象创建并下载txt文件将Canvas下载为一张图片HTML5 文件操作 file元素 语法 <input type&quo…

SpringIOC流程以及Mybatis架构

1、Spring IOC 流程图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/626a8582f4b14ac3983567a85bce1d4d.png IOC 依赖注入整体流程 1、环境初始化 2、Bean工厂初始化 3、读取项目配置 4、定义解析Bean-->BeanDefintion 5、将BeanDefinition存储工厂类的Map 6、通过…

Golang 将视频按照时间维度剪切 | Golang工具

目录 前言 环境依赖 代码 总结 前言 本文提供将视频按照时间维度进行剪切的工具方法&#xff0c;一如既往的实用主义。 主要也是学习一下golang使用ffmpeg工具的方式。 环境依赖 ffmpeg环境安装&#xff0c;可以参考我的另一篇文章&#xff1a;windows ffmpeg安装部署_阿…

2022 IoTDB Summit:IoTDB PMC 乔嘉林《端边云协同:Apache IoTDB 全新单机分布式架构》...

12 月 3 日、4日&#xff0c;2022 Apache IoTDB 物联网生态大会在线上圆满落幕。大会上发布 Apache IoTDB 的分布式 1.0 版本&#xff0c;并分享 Apache IoTDB 实现的数据管理技术与物联网场景实践案例&#xff0c;深入探讨了 Apache IoTDB 与物联网企业如何共建活跃生态&#…

具有循环条件gan的实值(医疗)时间序列生成-2017

REAL-VALUED (MEDICAL) TIME SERIES GENERATION WITH RECURRENT CONDITIONAL GANS ABSTRACT 生成对抗网络(GANs)作为一种训练模型以产生逼真数据的框架已经取得了显著的成功。在这项工作中&#xff0c;我们提出了循环GAN (RGAN)和循环条件GAN (RCGAN)来生成真实的实值多维时间…

canal实战问题汇总分析

canal在实战过程经常会遇到这样或者那样的问题&#xff0c;今天我们专门用一篇文章来列举分析一下&#xff0c;比如、JDK版meta.dat 中保存的位点信息和数据库的位点信息不一致本不匹配、bin-log信息消费失败等问题&#xff0c;下面我们开始一一分析&#xff1a; 1、数据库数据…

数据可视化软件有哪些?

随着大数据概念的普及与业务数据的爆炸式增长&#xff0c;越来越多的企业已经不满足于Excel的常规操作。 因为相较于以往PPT/Word/Excel数据汇报的形式而言&#xff0c;数据可视化平台包含了丰富的图表、组件信息&#xff0c;仅用一张屏幕就能够囊括诸多讯息&#xff0c;画面色…

2022全年度休闲食品(零食)十大热门品牌销量榜单

随着经济的发展及人们消费水平的提高&#xff0c;休闲食品作为居家出游的快消品&#xff0c;逐渐成为了人们生活中必不可少的一部分&#xff0c;同时&#xff0c;消费者对于休闲食品的数量和品质的需求也正不断增长。并且&#xff0c;在休闲食品的消费群体中&#xff0c;年轻群…

Eclipse插件之Tomcat Plugin 介绍、安装与使用

Tomcat Plugin 介绍 Eclipse Tomcat 插件为开发Java Web应用程序提供了Tomcat容器的简单集成。所谓的集成其实主要是以下功能&#xff1a; 在Eclispe中启动和关闭Tomcat启动后的应用可以很容易的打断点进行调试&#xff0c; 这一点应该是该插件最大的优势。 Tomcat 插件是Ec…

MySQL性能优化一 底层数据结构与算法

一 索引 索引 MySQL官网解释&#xff1a;索引是帮助MySQL高效获取数据的排好序的数据结构 索引数据结构&#xff1a; 二叉树红黑树Hash表B-Tree 案例&#xff1a;有一张两列七行的一个表t 假如我们的查找sql语句是&#xff1a; select * from t where t.col289;正常情况下…

Mysql process 问题,kill不用的process

这个一般会出现在连接池中&#xff0c;导致连接池数量不够然后连接失败&#xff0c;所以要kill 我们kill的都是sleep的&#xff0c;就是没有释放但是不用的链接 前言 sql中的show full processlist是查看线程&#xff0c;实际就是查这个表 select * from information_schema.…

16S全长测序解密转基因玉米根瘤菌群落组成

论文题目&#xff1a; Deciphering the rhizobacterial assemblages under the influence of genetically engineered maize carrying mcry genes 期刊&#xff1a; Environmental Science and Pollution Research 研究背景 玉米是我国的重要粮食作物&#xff0c;但虫害和草…

2023大厂招聘岗位数预测!明年哪些公司可以去?

winter is coming&#xff01;这一年C端要见顶、K12被团灭、阿里被监管&#xff0c;滴滴被处罚、华为都在力求在寒气中活下来&#xff0c;连大厂都深陷泥沼&#xff0c;更别说中小企业。 太多因素导致大批裁员&#xff0c;前不久&#xff0c;互联网er最后的梦乡虾皮大量裁员&am…

智能车|直流电机、编码器与驱动器

智能车|直流电机、编码器与驱动器直流电机直流电机原理减速器编码器编码器简介编码器的工作原理四倍频采集编码器采集程序实现驱动器TB6612FNG 电机驱动器TB6612FNG 的主要参数引脚说明电机整体接线直流电机 直流电机&#xff08;direct current machine&#xff09;是指能将直…