单链表的多语言表达:C++、Java、Python、Go、Rust

单链表

是一种链式数据结构,由一个头节点和一些指向下一个节点的指针组成。每个节点包含一个数据元素和指向下一个节点的指针。头节点没有数据,只用于表示链表的开始位置。

单链表的主要操作包括:

  1. 添加元素:在链表的头部添加新元素,需要修改头节点的指针。
  2. 删除元素:删除链表中的元素,需要修改头节点和其他节点的指针。
  3. 查找元素:在链表中查找某个元素,需要遍历整个链表。
  4. 遍历链表:按照链表的顺序依次访问每个元素,需要遍历整个链表。

单链表相对于数组的优点是插入和删除元素时不需要移动其他元素,时间复杂度为O(1)。但是,在查找元素时,单链表比数组要慢,时间复杂度为O(n)。

20210817204340750.png

本文总结了 C++、Java、Python、Go、Rust 五种语言的单链表的表达:

C++

c++语言既可以用struct也能用class来表示链表节点,类可以定义方法调用相对方便。另外C++类需要自定义析构函数用以退出时释放节点所占空间,其它语言有自动的垃圾回收机制。

struct 

// 定义结构体 Node,表示链表中的节点
struct Node {
    int data;  // 节点的数据
    Node* next;  // 指向下一个节点的指针
};

// 定义类 LinkedList,表示链表
class LinkedList {
private:
    Node* head;  // 指向链表头节点的指针
}

代码:

#include <iostream>

using namespace std;

// 定义结构体 Node,表示链表中的节点
struct Node {
    int data;  // 节点的数据
    Node* next;  // 指向下一个节点的指针
};

// 定义类 LinkedList,表示链表
class LinkedList {
private:
    Node* head;  // 指向链表头节点的指针

public:
    // 构造函数,初始化链表为空链表
    LinkedList() {
        head = NULL;
    }

    // 析构函数,释放链表中的所有节点
    ~LinkedList() {
        Node* curr = head;
        while (curr != NULL) {
            Node* next = curr->next;
            delete curr;
            curr = next;
        }
    }

    // 在链表头部添加一个新节点
    void add(int value) {
        Node* newNode = new Node;
        newNode->data = value;
        newNode->next = head;
        head = newNode;
    }

    // 在链表尾部添加一个新节点
    void push(int value) {
        Node* newNode = new Node;
        newNode->data = value;
        newNode->next = NULL;
        if (head == NULL) {
            head = newNode;
        } else {
            Node* curr = head;
            while (curr->next != NULL) {
                curr = curr->next;
            }
            curr->next = newNode;
        }
    }

    // 删除最后一个节点,并返回该节点的数据 
	int pop() {
	    if (head == NULL) {
	        return -1;
	    } else if (head->next == NULL) {
	        int data = head->data;
	        delete head;
	        head = NULL;
	        return data;
	    } else {
	        Node* curr = head;
	        while (curr->next->next != NULL) {
	            curr = curr->next;
	        }
	        int data = curr->next->data;
	        delete curr->next;
	        curr->next = NULL;
	        return data;
        }
	}

    // 遍历链表,打印每个节点的数据
    void traverse() {
        Node* curr = head;
        while (curr != NULL) {
            cout << curr->data << "->";
            curr = curr->next;
        }
        cout << "nil" << endl;
    }
};

int main() {
    LinkedList list;
    list.traverse();  // 打印空链表 nil
    list.add(1);  // 在链表头部添加节点 1
    list.traverse();  // 打印链表 1->nil
    list.add(2);  // 在链表头部添加节点 2
    list.traverse();  // 打印链表 2->1->nil
    list.add(3);  // 在链表头部添加节点 3
    list.traverse();  // 打印链表 3->2->1->nil
    list.push(4);  // 在链表尾部添加节点 4
    list.traverse();  // 打印链表 3->2->1->4->nil
    list.push(5);  // 在链表尾部添加节点 5
    list.traverse();  // 打印链表 3->2->1->4->5->nil
    cout << list.pop() << endl;  // 删除尾节点,并输出节点数据
    list.traverse();  // 打印链表 3->2->1->4->nil
    cout << list.pop() << endl;  // 删除尾节点,并输出节点数据
    list.traverse();  // 打印链表 3->2->1->nil
	return 0;
}

class

// 定义类 Node,表示链表中的节点
class Node {
public:
    int data;
    Node* next;
    Node(int value) {
        data = value;
        next = NULL;
    }
};

// 定义类 LinkedList,表示链表
class LinkedList {
private:
    Node* head;  // 指向链表头节点的指针
};

代码:

#include <iostream>

using namespace std;

// 定义类 Node,表示链表中的节点
class Node {
public:
    int data;
    Node* next;
    Node(int value) {
        data = value;
        next = NULL;
    }
};

// 定义类 LinkedList,表示链表
class LinkedList {
private:
    Node* head;  // 指向链表头节点的指针

public:
    // 构造函数,初始化链表为空链表
    LinkedList() {
        head = NULL;
    }

    // 析构函数,释放链表中的所有节点
    ~LinkedList() {
        Node* curr = head;
        while (curr != NULL) {
            Node* next = curr->next;
            delete curr;
            curr = next;
        }
    }

    // 在链表头部添加一个新节点
    void add(int value) {
        Node* newNode = new Node(value);
        newNode->next = head;
        head = newNode;
    }

    // 在链表尾部添加一个新节点
    void push(int value) {
        Node* newNode = new Node(value);
        newNode->next = NULL;
        if (head == NULL) {
            head = newNode;
        } else {
            Node* curr = head;
            while (curr->next != NULL) {
                curr = curr->next;
            }
            curr->next = newNode;
        }
    }

    // 删除最后一个节点,并返回该节点的数据 
	int pop() {
	    if (head == NULL) {
	        return -1;
	    } else if (head->next == NULL) {
	        int data = head->data;
	        delete head;
	        head = NULL;
	        return data;
	    } else {
		    Node* curr = head;
		    while (curr->next->next != NULL) {
		        curr = curr->next;
		    }
		    int data = curr->next->data;
		    delete curr->next;
		    curr->next = NULL;
	    	return data;
	    }
	}

    // 遍历链表,打印每个节点的数据
    void traverse() {
        Node* curr = head;
        while (curr != NULL) {
            cout << curr->data << "->";
            curr = curr->next;
        }
        cout << "nil" << endl;
    }
};

int main() {
    LinkedList list;
    list.traverse();  // 打印空链表 nil
    list.add(1);  // 在链表头部添加节点 1
    list.traverse();  // 打印链表 1->nil
    list.add(2);  // 在链表头部添加节点 2
    list.traverse();  // 打印链表 2->1->nil
    list.add(3);  // 在链表头部添加节点 3
    list.traverse();  // 打印链表 3->2->1->nil
    list.push(4);  // 在链表尾部添加节点 4
    list.traverse();  // 打印链表 3->2->1->4->nil
    list.push(5);  // 在链表尾部添加节点 5
    list.traverse();  // 打印链表 3->2->1->4->5->nil
    cout << list.pop() << endl;  // 删除尾节点,并输出节点数据
    list.traverse();  // 打印链表 3->2->1->4->nil
    cout << list.pop() << endl;  // 删除尾节点,并输出节点数据
    list.traverse();  // 打印链表 3->2->1->nil
	return 0;
}

Java

Java没有跟C或Go类似的struct结构体,只有用类class来表达。

class 

public class LinkedList {
    public class Node {
        public int data;
        public Node next;

        public Node(int value) {
            data = value;
            next = null;
        }
    }

    public LinkedList() {
        head = null;
    }
}

代码:

public class LinkedList {
    public class Node {
        public int data;
        public Node next;

        public Node(int value) {
            data = value;
            next = null;
        }
    }

    public LinkedList() {
        head = null;
    }

    private Node head;

    // 在链表头部添加一个新的节点
    public void add(int value) {
        Node newNode = new Node(value);
        newNode.next = head;
        head = newNode;
    }

    // 在链表尾部添加一个新的节点
    public void push(int value) {
        Node newNode = new Node(value);
        if (head == null) {
            head = newNode;
        } else {
            Node curr = head;
            while (curr.next != null) {
                curr = curr.next;
            }
            curr.next = newNode;
        }
    }

    // 删除尾节点,并返回该节点的数据
    public int pop() {
        if (head == null) {
            return -1;
        } else if (head.next == null) {
            int data = head.data;
            head = null;
            return data;
        } else {
            Node curr = head;
            while (curr.next.next != null) {
                curr = curr.next;
            }
            Node tail = curr.next;
            curr.next = null;
            return tail.data;
        }
    }

    // 遍历链表,打印每个节点的数据
    public void traverse() {
        Node curr = head;
        while (curr != null) {
            System.out.print(curr.data + "->");
            curr = curr.next;
        }
        System.out.println("nil");
    }

    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        list.traverse();  // 打印空链表 nil
        list.add(1);  // 在链表头部添加节点 1
        list.traverse();  // 打印链表 1->nil
        list.add(2);  // 在链表头部添加节点 2
        list.traverse();  // 打印链表 2->1->nil
        list.add(3);  // 在链表头部添加节点 3
        list.traverse();  // 打印链表 3->2->1->nil
        list.push(4);  // 在链表尾部添加节点 4
        list.traverse();  // 打印链表 3->2->1->4->nil
        list.push(5);  // 在链表尾部添加节点 5
        list.traverse();  // 打印链表 3->2->1->4->5->nil
        System.out.println(list.pop());  // 删除尾节点,并输出节点数据
        list.traverse();  // 打印链表 3->2->1->4->nil
        System.out.println(list.pop());  // 删除尾节点,并输出节点数据
        list.traverse();  // 打印链表 3->2->1->nil
    }
}

Python

Python也没有struct结构体,只能用类class来表达。而且python是动态类型语言,变量在创建时无需显式指定类型,也没有指针概念。

class 

class Node:
    def __init__(self, data):
        self.data = data  # 节点的数据
        self.next = None  # 节点的下一个指针,初始为空

class LinkedList:
    def __init__(self):
        self.head = None  # 链表的头指针,初始为空

代码:

class Node:
    def __init__(self, data):
        self.data = data  # 节点的数据
        self.next = None  # 节点的下一个指针,初始为空

class LinkedList:
    def __init__(self):
        self.head = None  # 链表的头指针,初始为空

    def add(self, data):
        # 在链表头部插入一个新节点
        newNode = Node(data)
        newNode.next = self.head
        self.head = newNode

    def push(self, data):
        # 在链表尾部添加一个新节点
        newNode = Node(data)
        if self.head is None:
            self.head = newNode
        else:
            curr = self.head
            while curr.next is not None:
                curr = curr.next
            curr.next = newNode

    def pop(self):
        # 删除尾节点,并返回该节点的值
        if self.head is None:
            return None
        if self.head.next is None:
            data = self.head.data
            self.head = None
            return data
        curr = self.head
        while curr.next.next is not None:
            curr = curr.next
        tail = curr.next
        curr.next = None
        return tail.data

    def traverse(self):
        # 遍历链表,打印每个节点的数据
        curr = self.head
        while curr is not None:
            print(curr.data, end='->')
            curr = curr.next
        print('nil')

if __name__ == '__main__':
    head = LinkedList() # 创建链表
    head.traverse()     # 遍历空链表
    head.add(1)         # 在链表头部添加节点 1
    head.traverse()     # 遍历链表 1->nil
    head.add(2)         # 在链表头部添加节点 2
    head.traverse()     # 遍历链表 2->1->nil
    head.add(3)         # 在链表头部添加节点 3
    head.traverse()     # 遍历链表 3->2->1->nil
    head.push(4)        # 在链表尾部添加节点 4
    head.traverse()     # 遍历链表 3->2->1->4->nil
    head.push(5)        # 在链表尾部添加节点 5
    head.traverse()     # 遍历链表 3->2->1->4->5->nil
    print(head.pop())   # 删除尾节点,并输出节点数据
    head.traverse()     # 打印链表 3->2->1->4->nil
    print(head.pop())   # 删除尾节点,并输出节点数据
    head.traverse()     # 打印链表 3->2->1->nil

Golang

Go没有class类,使用结构体 struct 来代替类。结构体可以包含字段(成员变量),并且可以定义方法(成员函数)来操作结构体的数据。

struct

type Node struct {
    data int
    next *Node
}

type LinkedList struct {
    head *Node
}

// 创建一个新的节点
func new(value int) *Node {
    return &Node{
        data: value,
        next: nil,
    }
}

代码:

package main

import "fmt"

type Node struct {
	data int
	next *Node
}

type LinkedList struct {
	head *Node
}

// 创建一个新的节点
func new(value int) *Node {
	return &Node{
		data: value,
		next: nil,
	}
}

// 在链表头部添加一个新节点
func (list *LinkedList) add(value int) {
	newNode := new(value)
	newNode.next = list.head
	list.head = newNode
}

// 在链表尾部添加一个新节点
func (list *LinkedList) push(value int) {
	newNode := new(value)
	if list.head == nil {
		list.head = newNode
	} else {
		curr := list.head
		for curr.next != nil {
			curr = curr.next
		}
		curr.next = newNode
	}
}

// 删除尾节点,并返回该节点的值
func (list *LinkedList) pop() int {
	if list.head == nil {
		return -1
	} else if list.head.next == nil {
		data := list.head.data
		list.head = nil
		return data
	} else {
		curr := list.head
		for curr.next.next != nil {
			curr = curr.next
		}
		tail := curr.next
		curr.next = nil
		return tail.data
	}
}

// 遍历链表,打印每个节点的数据
func (list *LinkedList) traverse() {
	curr := list.head
	for curr != nil {
		fmt.Printf("%d->", curr.data)
		curr = curr.next
	}
	fmt.Println("nil")
}

func main() {
	list := LinkedList{}
	list.traverse()         // 打印空链表 nil
	list.add(1)             // 在链表头部添加节点 1
	list.traverse()         // 打印链表 1->nil
	list.add(2)             // 在链表头部添加节点 2
	list.traverse()         // 打印链表 2->1->nil
	list.add(3)             // 在链表头部添加节点 3
	list.traverse()         // 打印链表 3->2->1->nil
	list.push(4)            // 在链表尾部添加节点 4
	list.traverse()         // 打印链表 3->2->1->4->nil
	list.push(5)            // 在链表尾部添加节点 5
	list.traverse()         // 打印链表 3->2->1->4->5->nil
	fmt.Println(list.pop()) // 删除尾节点,并打印数据
	list.traverse()         // 打印链表 3->2->1->4->nil
	fmt.Println(list.pop()) // 删除尾节点,并打印数据
	list.traverse()         // 打印链表 3->2->1->nil
}

Rust

Rust中也没有类的概念,但它提供了结构体 struct 和 trait 两种重要的机制来实现面向对象的编程风格。结构体用于定义数据结构,而 trait 则用于定义方法集合。

另外在Rust中,一般不使用unsafe指针std::ptr来操作链表,而是 Option 类型来表示链表指针,它代表的值可以存在(Some)也可以不存在(None)。Option 类型被广泛用于处理可能为空的值,以避免出现空指针异常。

struct

struct Node {
    data: i32,
    next: Option<Box<Node>>,
}

impl Node {
    fn new(value: i32) -> Node {
        Node { data: value, next: None }
    }
}

struct LinkedList {
    head: Option<Box<Node>>,
}

impl LinkedList {
    fn new() -> LinkedList {
        LinkedList { head: None }
    }
}

代码:

struct Node {
    data: i32,
    next: Option<Box<Node>>,
}

impl Node {
    fn new(value: i32) -> Node {
        Node { data: value, next: None }
    }
}

struct LinkedList {
    head: Option<Box<Node>>,
}

impl LinkedList {
    fn new() -> LinkedList {
        LinkedList { head: None }
    }

    // 在链表头部添加一个新节点
    fn add(&mut self, value: i32) {
        let mut new_node = Box::new(Node::new(value));
        new_node.next = self.head.take();
        self.head = Some(new_node);
    }

    // 在链表尾部添加一个新节点
    fn push(&mut self, value: i32) {
        let new_node = Box::new(Node::new(value));
        let mut curr = &mut self.head;
        while let Some(node) = curr {
            curr = &mut node.next;
        }
        *curr = Some(new_node);
    }

    // 删除尾节点,并返回该节点的数据
    fn pop(&mut self) -> Option<i32> {
        if self.head.is_none() {
            return None;
        }
        if self.head.as_ref().unwrap().next.is_none() {
            let data = self.head.take().unwrap().data;
            return Some(data);
        }
        let mut curr = self.head.as_mut().unwrap();
        while curr.next.as_ref().unwrap().next.is_some() {
            curr = curr.next.as_mut().unwrap();
        }
        let data = curr.next.take().unwrap().data;
        Some(data)
    }

    // 遍历链表,打印每个节点的数据
    fn traverse(&self) {
        let mut curr = &self.head;
        while let Some(node) = curr {
            print!("{}->", node.data);
            curr = &node.next;
        }
        println!("nil");
    }
}

fn main() {
    let mut list = LinkedList::new();
    list.traverse();  // 打印空链表 nil
    list.add(1);  // 在链表头部添加节点 1
    list.traverse();  // 打印链表 1->nil
    list.add(2);  // 在链表头部添加节点 2
    list.traverse();  // 打印链表 2->1->nil
    list.add(3);  // 在链表头部添加节点 3
    list.traverse();  // 打印链表 3->2->1->nil
    list.push(4);  // 在链表尾部添加节点 4
    list.traverse();  // 打印链表 3->2->1->4->nil
    list.push(5);  // 在链表尾部添加节点 5
    list.traverse();  // 打印链表 3->2->1->4->5->nil
    println!("{}", list.pop().unwrap());  // 删除尾节点,并输出节点数据
    list.traverse();  // 打印链表 3->2->1->4->nil
    println!("{}", list.pop().unwrap());  // 删除尾节点,并输出节点数据
    list.traverse();  // 打印链表 3->2->1->nil
}

struct unsafe

struct Node {
    data: i32,
    next: *mut Node,
}

impl Node {
    fn new(value: i32) -> Node {
        Node { data: value, next: std::ptr::null_mut() }
    }
}

struct LinkedList {
    head: *mut Node,
}

impl LinkedList {
    fn new() -> LinkedList {
        LinkedList { head: std::ptr::null_mut() }
    }
}

代码:

struct Node {
    data: i32,
    next: *mut Node,
}

impl Node {
    fn new(value: i32) -> Node {
        Node { data: value, next: std::ptr::null_mut() }
    }
}

struct LinkedList {
    head: *mut Node,
}

impl LinkedList {
    fn new() -> LinkedList {
        LinkedList { head: std::ptr::null_mut() }
    }

    fn add(&mut self, value: i32) {
        let mut new_node = Box::new(Node::new(value));
        new_node.next = self.head;
        self.head = Box::into_raw(new_node);
    }

    fn push(&mut self, value: i32) {
        let new_node = Box::new(Node::new(value));
        let mut curr = &mut self.head;
        while !(*curr).is_null() {
            curr = unsafe { &mut (**curr).next };
        }
        *curr = Box::into_raw(new_node);
    }

    fn pop(&mut self) -> Option<i32> {
        if self.head.is_null() {
            return None;
        }
        let mut curr = self.head;
        let mut prev = std::ptr::null_mut();
        while unsafe { !(*curr).next.is_null() } {
            prev = curr;
            curr = unsafe { (*curr).next };
        }
        let data = unsafe { Box::from_raw(curr) }.data;
        if prev.is_null() {
            self.head = std::ptr::null_mut();
        } else {
            unsafe { (*prev).next = std::ptr::null_mut(); }
        }
        Some(data)
    }

    fn traverse(&self) {
        let mut curr = self.head;
        while !curr.is_null() {
            unsafe {
                print!("{}->", (*curr).data);
                curr = (*curr).next;
            }
        }
        println!("nil");
    }

    fn cleanup(&mut self) {
        let mut curr = self.head;
        while !curr.is_null() {
            let next = unsafe { (*curr).next };
            unsafe { Box::from_raw(curr) };
            curr = next;
        }
    }
}

fn main() {
    let mut list = LinkedList::new();
    list.traverse();  // 打印空链表 nil
    list.add(1);
    list.traverse();
    list.add(2);
    list.traverse();
    list.add(3);
    list.traverse();
    list.push(4);
    list.traverse();
    list.push(5);
    list.traverse();
    println!("{}", list.pop().unwrap());
    list.traverse();
    println!("{}", list.pop().unwrap());
    list.traverse();
    list.cleanup();
}

cleanup()相当于析构函数,用于释放链表所占空间。


以上所有示例代码的输出都相同:

nil
1->nil
2->1->nil
3->2->1->nil
3->2->1->4->nil
3->2->1->4->5->nil
5
3->2->1->4->nil
4
3->2->1->nil

其中,Rust的节点值有点特殊,使用了Some类型。比如:

使用println!("{:?}", list.pop());  不需要pop()后面的.unwrap(),返回Some(n);当链表为空时,直接返回None。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

采用typescript编写,实现ofd前端预览、验章

前言 浏览器内核已支持pdf文件的渲染&#xff0c;这极大的方便了pdf文件的阅读和推广。ofd文件作为国产板式标准&#xff0c;急需一套在浏览器中渲染方案。 本人研究ofd多年&#xff0c;分别采用qt、c# 开发了ofd阅读器。本人非前端开发人员&#xff0c;对js、typescript并不熟…

工程管理与工作流

1 统一开发环境/ 协作工具 你知道开发环境指的是什么吗&#xff1f; 开发环境&#xff1a; 工程运行环境、开发工具/ 编辑器 、开发依赖环境、 配置文件 软件环境&#xff1a; “仿真预演”环境 Staging 生产环境前最终验证、 这一环境尽可能的仿真了真实的生产环境 、另一个…

自己实现 SpringMVC 底层机制 系列之-实现任务阶段 6-完成控制器方法获取参数-@RequestParam

&#x1f600;前言 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 6-完成控制器方法获取参数-RequestParam &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c…

网络编程——网络基础知识

目录 一、网络历史两个重要名词1.1 阿帕网1.2 TCP/IP协议 二、局域网和广域网三、IP地址3.1 基本概念3.2 划分(IPV4)3.3 特殊IP地址3.4 子网掩码3.5 重新组网 四、网络模型4.1 网络的体系结构&#xff1a;4.2 OSI与TCP/IP模型4.2.1 OSI模型4.2.2 TCP/IP模型4.2.3 OSI和TCP/IP模…

CNN之图像识别

什么是图像识别 • 图像识别技术是信息时代的一门重要的技术&#xff0c;其产生目的是为了让计算机代替人类去处理大量的物理信息。随着计算机技术的发展&#xff0c;人类对图像识别技术的认识越来越深刻 • 图像识别技术的定义为利用计算机对图像进行处理、分析和理解&…

Docker(二) Docker容器

在docker中的容器都是由镜像所创建的&#xff0c;一个镜像可以创建多个容器。 一、调试Docker 启动Docker systemctl start docker 查看Docker中有哪些镜像 docker images 下载镜像 docker pull hello-world 运行镜像 docker run hello-world 出现 Hello from Docker! 这…

构建系统自动化-autoreconf

autoreconf简介 autoreconf是一个GNU Autotools工具集中的一个命令&#xff0c;用于自动重新生成构建系统的配置脚本和相关文件。 Autotools是一组用于自动化构建系统的工具&#xff0c;包括Autoconf、Automake和Libtool。它们通常用于跨平台的软件项目&#xff0c;以便在不同…

[C语言]分支与循环

导言&#xff1a; 在人生中我们总会有选择&#xff0c;**如下一顿吃啥&#xff1f;**又或者每天都是在重复&#xff0c;吃饭&#xff01;&#xff01;&#xff01;&#xff01;&#xff0c;当然在C语言中也有选择和重复那就是分支语句与循环语句 文章目录 分支循环循环中的关键…

手写代码-前端面试

GitHub&#xff1a;手写代码集合

大数据-玩转数据-Flink营销对账

一、说明 在电商网站中&#xff0c;订单的支付作为直接与营销收入挂钩的一环&#xff0c;在业务流程中非常重要。对于订单而言&#xff0c;为了正确控制业务流程&#xff0c;也为了增加用户的支付意愿&#xff0c;网站一般会设置一个支付失效时间&#xff0c;超过一段时间不支…

一云多芯,智能化转型的下一个工程化挑战

进入2023年&#xff0c;产业数字化和智能化转型升级进入了大规模工程化落地阶段。根据中国信通院《中国数字经济发展研究报告&#xff08;2023&#xff09;》&#xff0c;数字经济已经占我国GDP比重达到41.5%&#xff0c;相当于第二产业占国民经济的比重。随着产业数字化和智能…

【数据结构】 LinkedList的模拟实现与使用

文章目录 &#x1f340;什么是LinkedList&#x1f334;LinkedList的模拟实现&#x1f6a9;创建双链表&#x1f6a9;头插法&#x1f6a9;尾插法&#x1f6a9;任意位置插入&#x1f6a9;查找关键字&#x1f6a9;链表长度&#x1f6a9;打印链表&#x1f6a9;删除第一次出现关键字为…

YOLOv5+deepsort实现目标追踪。(附有各种错误解决办法)

一、YOLOv5算法相关配置 🐸这里如果是自己只想跑一跑YOLOV5的话,可以参考本章节。只想跑通YOLOv5+deepsort的看官移步到下一章节。 1.1 yolov5下载 🐸yolov5源码在github下载地址上或者Gitee上面都有。需要注意的是由于yolov5的代码库作者一直在维护,所以下载的时候需…

【Unity小技巧】Unity探究自制对象池和官方内置对象池(ObjectPool)的使用

文章目录 前言不使用对象池使用官方内置对象池应用 自制对象池总结源码参考完结 前言 对象池&#xff08;Object Pool&#xff09;是一种软件设计模式&#xff0c;用于管理和重用已创建的对象。在对象池中&#xff0c;一组预先创建的对象被维护在一个池中&#xff0c;并在需要时…

OJ练习第152题——分割回文串 II

分割回文串 II 力扣链接&#xff1a;132. 分割回文串 II 题目描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是回文。 返回符合要求的 最少分割次数 。 示例 Java代码 class Solution {public int minCut(String s) {int n s.leng…

听说你还不知道什么是python?本文将带你发掘python的魅力并让你爱上他

文章目录 前言什么是pythonpython的由来我们为什么要学习python帮助python学习的网站总结 前言 各位朋友们&#xff0c;大家好。龙叔我后台经常收到私信问什么是Python&#xff1f;有必要学习这门语言么&#xff1f;今天&#xff0c;将通过本文告知大家Python是什么&#xff1…

浅谈日常使用的 Docker 底层原理-三大底座

适合的读者&#xff0c;对Docker有过简单了解的朋友&#xff0c;想要进一步了解Docker容器的朋友。 前言 回想我这两年&#xff0c;一直都是在使用 Docker&#xff0c;看过的视频、拜读过的博客&#xff0c;大都是在介绍 Docker 的由来、使用、优点和发展趋势&#xff0c;但对…

QT学习笔记-开发环境编译Qt MySql数据库驱动与交叉编译Qt MySql数据库驱动

QT学习笔记-开发环境编译Qt MySql数据库驱动与交叉编译Qt MySql数据库驱动 0、背景1、基本环境2、开发环境编译Qt MySql数据库驱动2.1 依赖说明2.2 MySQL驱动编译过程 3、交叉编译Qt MySql数据库驱动3.1 依赖说明3.3.1 如何在交叉编译服务器上找到mysql.h及相关头文件3.3.2 如果…

【PHP】基础语法变量常量

文章目录 PHP简介前置知识了解静态网站的特点动态网站特点 PHP基础语法代码标记注释语句分隔(结束)符变量变量的基本概念变量的使用变量命名规则预定义变量可变变量变量传值内存分区 常量基本概念常量定义形式命名规则使用形式系统常量魔术常量 PHP简介 PHP定义&#xff1a;一…

【服务器】Strace显示后台进程输出

今天有小朋友遇到一个问题 她想把2331509和2854637这两个进程调到前台来&#xff0c;以便于在当前shell查看这两个python进程的实时输出 我第一反应是用jobs -l然后fg &#xff08;参考这里&#xff09; 但是发现jobs -l根本没有输出&#xff1a; 原因是jobs看的是当前ses…
最新文章