java实现的无头单向非循环链表

news2024/11/23 12:04:32

java实现的无头单向非循环链表

  • ArrayList的缺陷
  • 链表
    • 链表的概念及结构
    • 无头单向非循环链表的实现
    • 链表OJ题

ArrayList的缺陷

由于ArrayList底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为O(N),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景,因此java集合中又引入了LinkedList,即链表结构。

链表

链表的概念及结构

链表是一种物理存储结构上非连续的存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的。在这里插入图片描述
链式结构在逻辑上是连续的,但是在物理上不一定连续,现实中的结点一般是从堆上申请出来的,从堆上申请的空间,是按照一定的策略来分配的,两次申请的空间可能连续,也可能不连续
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:

  1. 单向或者双向
    在这里插入图片描述

  2. 带头或者不带头
    在这里插入图片描述

  3. 循环或者非循环

在这里插入图片描述
所以有八种链表结构
单向带头循环链表,双向带头循环链表
单向不带头循环链表,双向不带头循环链表
单向带头非循环链表,双向带头非循环链表
单向不带头非循环链表,双向不带头非循环链表
虽然有这么多的链表的结构,重点需要我们掌握两种:

  • 无头单向非循环链表:结构简单,一般不会单独用来存数据,实际中更多是作为其他数据结构的子结构,如哈希,图的邻接表等等
  • 无头双向链表:在java的集合框架中LinkedList底层实现就是无头双向循环链表。

无头单向非循环链表的实现

public interface IList {
    //头插法
    public void addFirst(int data);
    //尾插法
    public void addLast(int data);
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data);
    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key);
    //删除第一次出现关键字为key的节点
    public void remove(int key);
    //删除所有值为key的节点
    public void removeAllKey(int key);
    //得到单链表的长度
    public int size();
    public void clear();
    public void display();
}
public class MySingleList implements IList{

    //静态内部类创建节点
    static class LinkNode{
        public int value;
        public LinkNode next;

        public LinkNode(int value) {
            this.value = value;
        }
    }

    public LinkNode head;

    @Override
    public void addFirst(int data) {

    }

    @Override
    public void addLast(int data) {

    }

    @Override
    public void addIndex(int index, int data) {

    }

    @Override
    public boolean contains(int key) {
        return false;
    }

    @Override
    public void remove(int key) {

    }

    @Override
    public void removeAllKey(int key) {

    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public void clear() {

    }

    @Override
    public void display() {

    }
}

我们先从打印链表开始,如果我们使用head引用来遍历打印,直到遇到null,到最后head到了null,我们就找不到头节点了,所以我们可以另外使用一个cur引用来遍历。

@Override
public void display() {
    LinkNode cur = this.head;
    while(cur != null){
        System.out.print(cur.value + " ");
        cur = cur.next;
    }
    System.out.println();
}

我们可以通过自己手动创建链表,来测试我们的打印链表方法

public void createSingleLink(){
    LinkNode node0 = new LinkNode(12);
    LinkNode node1 = new LinkNode(23);
    LinkNode node2 = new LinkNode(34);
    LinkNode node3 = new LinkNode(45);
    LinkNode node4 = new LinkNode(56);

    this.head = node0;
    node0.next = node1;
    node1.next = node2;
    node2.next = node3;
    node3.next = node4;
    node4.next = null;
}
public class Test {
    public static void main(String[] args) {
        MySingleList list = new MySingleList();
        list.createSingleLink();
        list.display();
    }
    //结果为:12 23 34 45 56 
}

接下来实现size()求链表节点个数,依然通过一个cur来遍历并计数。

@Override
public int size() {
    int count = 0;
    LinkNode cur = this.head;
    while(cur != null){
        count++;
        cur = cur.next;
    }
    return count;
}
public class Test {
    public static void main(String[] args) {
        MySingleList list = new MySingleList();
        list.createSingleLink();
        System.out.println(list.size());
    }
    //结果为:5
}

接下来实现查找是否包含关键字key是否在单链表当中的方法,我们依然通过遍历找到该key,返回true,找不到返回false

@Override
public boolean contains(int key) {
     LinkNode cur = this.head;
     while(cur != null){
         if(cur.value == key){
             return true;
         }
         cur = cur.next;
     }
     return false;
 }
public class Test {
    public static void main(String[] args) {
        MySingleList list = new MySingleList();
        list.createSingleLink();
        //12 23 34 45 56
        System.out.println(list.contains(12));
        System.out.println(list.contains(34));
        System.out.println(list.contains(56));
        System.out.println(list.contains(100));
    }
    //结果为:true
    //true
    //true
    //false
}

接下来实现头插法,也就是在链表头部插入节点
在这里插入图片描述

@Override
public void addFirst(int data) {
    LinkNode newNode = new LinkNode(data);
    newNode.next = this.head;
    this.head = newNode;
}
public class Test {
    public static void main(String[] args) {
        MySingleList list1 = new MySingleList();
        list1.createSingleLink();
        list1.addFirst(99);
        list1.display();
        MySingleList list = new MySingleList();
        list.addFirst(56);
        list.addFirst(45);
        list.addFirst(34);
        list.addFirst(23);
        list.addFirst(12);
        list.addFirst(99);
        list.display();
    }
    //结果为:
    //99 12 23 34 45 56
    //99 12 23 34 45 56
}

接下来实现尾插法,我们需要先找到尾节点,再进行插入,还有我们还要考虑到如果链表为空时,代码是否能执行,是否需要我们再对其另外的实现
在这里插入图片描述
在这里插入图片描述

@Override
public void addLast(int data) {
    LinkNode newNode = new LinkNode(data);
    //如果链表为空
    if(this.head == null){
        this.head = newNode;       //直接将head指向新结点
        return;
    }
    //链表非空
    //首先找到尾结点
    LinkNode cur = this.head;
    while(cur.next != null){    //当cur走到尾结点,cur.next == null退出循环,cur指向尾结点
        cur = cur.next;
    }
    cur.next = newNode;
}
public class Test {
    public static void main(String[] args) {
        MySingleList list = new MySingleList();
        list.addLast(12);
        list.addLast(23);
        list.addLast(34);
        list.addLast(45);
        list.addLast(56);
        list.addLast(99);
        list.display();
    }
    //结果为:
    //12 23 34 45 56 99
}

接下来实现任意位置插入的方法,第一个数据节点为0号下标,任意位置插入涉及尾插,头插,还有中间插入,中间插入需要修改前后指向,所以需要找到插入位置的前一个,就可以实现互相绑定,而且绑定有一个规律:所有的绑定,优先绑定后面。如果优先绑定前面,可能会出现问题,例如该方法。还有我们要考虑到任意位置,是所有位置吗,我们还需要对index进行检查,不能小于0,也不能大于size();
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果先绑定前面会出现什么问题呢?
在这里插入图片描述

public class IndexIllegal extends RuntimeException{
    public IndexIllegal() {
    }

    public IndexIllegal(String message) {
        super(message);
    }
}
private void checkIndex(int index) throws IndexIllegal{
    if(index < 0 || index > size()){
        throw new IndexIllegal("插入位置不合法");
    }
}

@Override
public void addIndex(int index, int data) {
    try{
        checkIndex(index);
        int len = size();   //用一个变量存储就不用一直调用方法
        if(index == 0){
            addFirst(data);
            return;
        }
        if(index == len){
            addLast(data);
            return;
        }
        LinkNode newNode = new LinkNode(data);
        LinkNode cur = this.head;
        while(index - 1 != 0){
            cur = cur.next;
            index--;
        }
        newNode.next = cur.next;
        cur.next = newNode;
    }catch(IndexIllegal e){
        e.printStackTrace();
    }

}
public class Test {
    public static void main(String[] args) {
        MySingleList list = new MySingleList();
        list.addLast(12);
        list.addLast(23);
        list.addLast(34);
        list.addLast(45);
        list.addLast(56);
        list.display();
        list.addIndex(0,11);
        list.display();
        list.addIndex(6,66);
        list.display();
        list.addIndex(3,33);
        list.display();
        //list.addIndex(100,77);
    }
    //结果为:
    //12 23 34 45 56
    //11 12 23 34 45 56
    //11 12 23 34 45 56 66
    //11 12 23 33 34 45 56 66
}

接下来实现删除第一次出现关键字为key的节点的方法
在这里插入图片描述

在这里插入图片描述

@Override
public void remove(int key) {
    if(this.head == null){
        return;
    }
    if(this.head.value == key){
        this.head = this.head.next;
        return;
    }
    LinkNode cur = this.head;
    while(cur.next != null){
        if(cur.next.value == key){
            LinkNode del = cur.next;
            cur.next = del.next;    //也可以写成 cur.next = cur.next.next;
            return;
        }
        cur = cur.next;
    }
}
public class Test {
    public static void main(String[] args) {
        MySingleList list = new MySingleList();
        list.addLast(12);
        list.addLast(23);
        list.addLast(34);
        list.addLast(45);
        list.addLast(56);
        list.display();
        list.remove(12);
        list.display();
        list.remove(56);
        list.display();
        list.remove(34);
        list.display();
    }
    //结果为:
    //12 23 34 45 56 
    //23 34 45 56 
    //23 34 45 
    //23 45 
}

接下来实现删除所有值为key的节点的方法
在这里插入图片描述
在这里插入图片描述

@Override
public void removeAllKey(int key) {
    //如果链表为空,不能删
    if(this.head == null){
        return;
    }
    LinkNode prev = this.head;
    LinkNode cur = this.head.next;
    while(cur != null){
        if(cur.value == key){
            prev.next = cur.next;
            cur = cur.next;
        }else{
            prev = cur;
            cur = cur.next;
        }
    }
    if(this.head.value == key){
        this.head = this.head.next;
    }
}
public class Test {
    public static void main(String[] args) {
        MySingleList list = new MySingleList();
        list.addLast(23);
        list.addLast(23);
        list.addLast(34);
        list.addLast(23);
        list.addLast(56);
        list.display();
        list.removeAllKey(23);
        list.display();
    }
    //结果为:
    //23 23 34 23 56 
    //34 56
}

最后我们要实现的是清空链表
在这里插入图片描述

@Override
public void clear() {
    LinkNode cur = this.head;
    while(cur != null){
        LinkNode curN = cur.next;
        cur.next = null;
        cur = curN;
    }
    this.head = null;
}
public class Test {
    public static void main(String[] args) {
        MySingleList list = new MySingleList();
        list.addLast(23);
        list.addLast(23);
        list.addLast(34);
        list.addLast(23);
        list.addLast(56);
        list.display();
        list.clear();
        list.display();
    }
    //结果为:
    //23 23 34 23 56
    //
}

链表OJ题

  1. 反转一个单链表。 链接
    给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null){
            return head;
        }
        ListNode cur = head.next;
        head.next = null;
        while(cur != null){
            ListNode curN = cur.next;
            cur.next = head;
            head = cur;
            cur = curN;
        }
        return head;

    }
}
  1. 给定一个带有头结点head的非空链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。 链接
    给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode middleNode(ListNode head) {
    	if(head == null){
            return head;
        }
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
}
  1. 输入一个链表,输出该链表中倒数第k个节点。 链接
    实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。
    说明:给定的 k 保证是有效的。
    在这里插入图片描述
    在这里插入图片描述
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public int kthToLast(ListNode head, int k) {
        if(head == null){
            return -1;
        }
        if(k < 0){
            return -1;
        }
        //需要求长度
        // if(k > 5){
        //     return -1;
        // }
        ListNode slow = head;
        ListNode fast = head;
        while(k - 1 != 0){
            fast = fast.next;
            if(fast == null){
                return -1;
            }
            k--;
        }
        while(fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        return slow.val;
    }
}
  1. 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。链接
    将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
    在这里插入图片描述
    在这里插入图片描述
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if(list1 == null){
            return list2;
        }
        if(list2 == null){
            return list1;
        }
        ListNode newH = new ListNode(-1);
        ListNode tmp = newH;
        while(list1 != null && list2 != null){
            if(list1.val < list2.val){
                tmp.next = list1;
                tmp = tmp.next;
                list1 = list1.next;
            }else{
                tmp.next = list2;
                tmp = tmp.next;
                list2 = list2.next;
            }
        }
        if(list1 != null){
            tmp.next = list1;
        }
        if(list2 != null){
            tmp.next = list2;
        }
        return newH.next;
    }
}
  1. 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 。链接
    现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
    在这里插入图片描述
    在这里插入图片描述
import java.util.*;

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Partition {
    public ListNode partition(ListNode pHead, int x) {
        // write code here
        ListNode cur = pHead;
        ListNode beforeBegin = null;
        ListNode beforeEnd = null;
        ListNode afterBegin = null;
        ListNode afterEnd = null;
        while(cur != null){
            if(cur.val < x){
                if(beforeBegin == null){
                    beforeBegin = beforeEnd = cur;
                }else{
                    beforeEnd.next = cur;
                    beforeEnd = beforeEnd.next;
                }
            }else{
                if(afterBegin == null){
                    afterBegin = afterEnd = cur;
                }else{
                    afterEnd.next = cur;
                    afterEnd = afterEnd.next;
                }
            }
            cur = cur.next;
        }
        if(beforeBegin == null){
            return afterBegin;
        }
        beforeEnd.next = afterBegin;
        if(afterEnd != null){
            afterEnd.next = null;
        }
        return beforeBegin;
    }
}
  1. 链表的回文结构。
    对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
    给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
    链接
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
import java.util.*;

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class PalindromeList {
    public boolean chkPalindrome(ListNode A) {
        // write code here
        ListNode slow = A;
        ListNode fast = A;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode cur = slow.next;
        while(cur != null){
            ListNode curN = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curN;
        }
        fast = A;
        while(fast != slow){
            if(slow.val != fast.val){
                return false;
            }
            if(fast.next == slow){
                return true;
            }
            slow = slow.next;
            fast = fast.next;
        }
        return true;
    }
}
  1. 输入两个链表,找出它们的第一个公共结点。链接
    给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交:

在这里插入图片描述

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode pLong = headA;
        ListNode pShort = headB;
        int lenA = 0;
        int lenB = 0;
        while(pLong != null){
            lenA++;
            pLong = pLong.next;
        }
        while(pShort != null){
            lenB++;
            pShort = pShort.next;
        }
        pLong = headA;
        pShort = headB;
        int len = lenA - lenB;
        if(len < 0){
            pLong = headB;
            pShort = headA;
            len = lenB - lenA;
        }
        while(len != 0){
            pLong = pLong.next;
            len--;
        }
        while(pLong != pShort){
            pLong = pLong.next;
            pShort = pShort.next;
        }
        if(pLong == null){
            return null;    //没相交
        }
        return pLong;
    }
}
  1. 给定一个链表,判断链表中是否有环。链接
    给你一个链表的头节点 head ,判断链表中是否有环。
    如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
    如果链表中存在环 ,则返回 true 。 否则,返回 false 。
    在这里插入图片描述
    思路:快慢指针,即慢指针一次走一步,快指针一次走两步,两个指针从链表起始位置开始运行,如果链表带环则一定会在环中相遇,否则快指针率先走到链表是末尾。
  • 为什么指针每次走两步,慢指针走一步可以?
    假设链表带环,两个指针最后都会进入环,快指针先进环,慢指针后进环,当慢指针刚进环时,可能就和快指针相遇了,最差情况下两个指针之间的距离刚好就是环的长度,此时两个指针每移动一次,之间的距离就缩小一步,不会出现每次刚好是套圈的情况,因此:在慢指针走到一圈之前,快指针肯定是可以追上慢指针的,即相遇。
  • 快指针一次走3步,走4步,…n步行吗?
    在这里插入图片描述
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                return true;
            }
        }
        return false;
    }
}
  1. 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 NULL。链接
    给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
    如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
    不允许修改链表。
    示例 1:
    在这里插入图片描述
    输入:head = [3,2,0,-4], pos = 1
    输出:返回索引为 1 的链表节点
    解释:链表中有一个环,其尾部连接到第二个节点。
    示例 2:
    在这里插入图片描述
    输入:head = [1], pos = -1
    输出:返回 null
    解释:链表中没有环。
    在这里插入图片描述
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                break;
            }
        }
        if(fast == null  || fast.next == null){
            return null;
        }
        slow = head;
        while(slow != fast){
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}

对于无头单向非循环链表就学习到这了,希望这篇文章对你有帮助。

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

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

相关文章

使用C语言获取iostat中的await值的方法和方案

使用C语言获取iostat中的await值的方法和方案 1. 准备工作2. 调用iostat命令并获取输出3. 解析iostat输出4. 完整实现和错误处理5. 注意事项在Linux系统中,iostat命令是sysstat软件包的一部分,用于监控系统的CPU、网卡、tty设备、磁盘、CD-ROM等设备的活动情况和负载信息。其…

逻辑回归(下): Sigmoid 函数的发展历史

背景 闲来无事翻了一下之前买的一个机器学习课程及之前记录的网络笔记&#xff0c;发现遇到公式都是截图&#xff0c;甚至是在纸上用笔推导的。重新整理一遍之前逻辑回归函数的学习笔记&#xff0c;主要是为了玩一下 LaTex 语法&#xff0c;写公式挺有意思的。 整理之前三篇笔…

VMware 虚拟机 下载安装 Centos7 和Windows10 镜像源

准备工作 下载 VMware链接&#xff1a;稍后发布链接 Centos7完整版链接&#xff1a;https://www.123865.com/ps/EF7OTd-mdAnH Centos7mini版链接&#xff1a;https://www.123865.com/ps/EF7OTd-1dAnH Windows10链接&#xff1a;https://www.123865.com/ps/EF7OTd-4dAnH 演示环境…

win11任务栏颜色怎么修改?透明任务栏效果可以实现吗?5套方案!

win11任务栏颜色怎么修改&#xff1f; ■ 通过系统个性化设置、任务栏设置、金舟Translucent任务栏、Glass8、注册表等方式可以快速修改Windows11电脑任务栏颜色。 在重度使用电脑办公的过程中&#xff0c;大家除了对电脑壁纸有一点的设计感外&#xff0c;小编发现不少人对电…

【Qt】Qt安装(2024-10,QT6.7.3,Windows,Qt Creator 、Visual Studio、Pycharm 示例)

文章目录 一、Qt 简介二、安装开源版本2.1 Qt 官网 与 版本选择2.2 Qt 安装程序 三、使用示例3.1 Qt Creator3.11 示例程序3.12 新建C项目3.13 新建Python项目 3.2 Visual Studio 附录附录 1&#xff1a;Additional Libraries 说明附录2 &#xff1a;老版本安装附录3&#xff1…

基于大数据架构的就业岗位推荐系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

Redis入门第一步:认识Redis与快速安装配置

认识Redis与快速安装配置&#x1f343; Redis是什么&#x1f432; 1.Redis的背景&#x1f38d; Redis&#xff08;Remote Dictionary Server&#xff09;译为"远程字典服务"&#xff0c;它是一款基于内存实现的键值型 NoSQL 数据库&#xff0c; 通常也被称为数据结…

An End-to-End Local Attention Based Model for Table Recognition(ICDAR 2023)

An End-to-End Local Attention Based Model for Table Recognition(ICDAR 2023) 一.前述 作者认为基于Transformer的表格识别模型很难处理大表格的识别&#xff0c;原因是受限于它的全局注意力global attention机制。 基于以上&#xff0c;作者提出了一种局部注意力local a…

【HTML并不简单】笔记1-常用rel总结:nofollow、noopener、opener、noreferrer,relList

文章目录 rel"nofollow"rel"noopener"与rel"opener"rel"noreferrer"relList对象 《HTML并不简单&#xff1a;Web前端开发精进秘籍》张鑫旭&#xff0c;一些摘要&#xff1a; HTML&#xff0c;这门语言的知识体系非常庞杂&#xff0c;涉…

Windows开发工具使用技巧全面指南

目录 目录 Visual Studio 功能概述 使用技巧 快捷键表 Visual Studio Code 功能概述 常用扩展 使用技巧 PowerShell 功能概述 常用命令 脚本编写技巧 Git for Windows 功能概述 集成技巧 常用命令表 调试工具 Visual Studio调试器 使用技巧 WinDbg 使用技…

828华为云征文|部署音乐流媒体服务器 mStream

828华为云征文&#xff5c;部署音乐流媒体服务器 mStream 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 mStream3.1 mStream 介绍3.2 mStream 部署3.3 mStream 使用 四、…

UE4完整教程 UE4简介 UE4学习攻略及文件格式

开头附上工作招聘面试必备问题噢~~包括综合面试题、无领导小组面试题资源文件免费!全文干货。 UE4简介学习攻略UE4Demo代码面试内容资源-CSDN文库https://download.csdn.net/download/m0_72216164/89825102 工作招聘无领导小组面试全攻略最常见面试题(第一部分)共有17章+可…

PCL 点云模型滤波(圆形)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 生成点云数据 2.1.2 模型滤波函数 2.1.3 可视化函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xf…

「JavaScript深入」彻底理解JS中的闭包

JavaScript深入 — 闭包 一、概念二、示例三、实用的闭包四、用闭包模拟私有方法五、一个常见错误&#xff1a;在循环中创建闭包&#x1f330; 另一个经典例子-定时器与闭包 六、优劣好处坏处解决 七、图解闭包八、应用 &#x1f4aa;封装私有变量函数工厂异步操作中的回调函数…

css中背景色、背景图的使用

1、同时使用背景色、背景图片 参考链接&#xff1a;链接 以下样式&#xff0c;背景色在图片下方(缺点&#xff1a;图片不透明时&#xff0c;背景色会被完全遮挡。) .header {height: 100%;width: 100%;background-color: #000;background-image: url(/static/images/back.pn…

云原生之运维监控实践-使用Prometheus与Grafana实现对MySQL和Redis服务的监测

背景 如果你要为应用程序构建规范或用户故事&#xff0c;那么务必先把应用程序每个组件的监控指标考虑进来&#xff0c;千万不要等到项目结束或部署之前再做这件事情。——《Prometheus监控实战》 去年写了一篇在Docker环境下部署若依微服务ruoyi-cloud项目的文章&#xff0c;当…

数据结构之手搓顺序表(顺序表的增删查改)

目录 文章目录 前言 一、什么是顺序表&#xff1f; 二、动态顺序表的实现 1.头文件定义 2.实现顺序表的初始化 3.检查顺序表空间容量是否足够&#xff0c;不够就增容 4.顺序表的销毁 5.顺序表的打印 6.顺序表的尾插 7.顺序表的头插 8.顺序表的头删 9.顺序表的尾删 10.顺序…

LeetCode题练习与总结:二叉树的所有路径--257

一、题目描述 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5] 输出&#xff1a;["1->2->5","1->…

RabbitMQ基本原理

一、基本结构 所有中间件技术都是基于 TCP/IP 协议基础之上进行构建新的协议规范&#xff0c;RabbitMQ遵循的是AMQP协议&#xff08;Advanced Message Queuing Protocol - 高级消息队列协议&#xff09;。 生产者发送消息流程&#xff1a; 1、生产者和Broker建立TCP连接&#…

国庆同欢,祖国昌盛!肌肉纤维启发,水凝胶如何重构聚合物

在这个国庆佳节&#xff0c;我们共同感受祖国的繁荣昌盛&#xff0c;同时也迎来了知识的探索之旅。今天来了解聚合物架构的重构的研究——《Hydrogel‐Reactive‐Microenvironment Powering Reconfiguration of Polymer Architectures》发表于《Advanced Science》。材料科学不…