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

news/2024/4/27 22:07:02/文章来源:https://blog.csdn.net/boysoft2002/article/details/132000754

单链表

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

单链表的主要操作包括:

  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();  // 打印空链表 nillist.add(1);  // 在链表头部添加节点 1list.traverse();  // 打印链表 1->nillist.add(2);  // 在链表头部添加节点 2list.traverse();  // 打印链表 2->1->nillist.add(3);  // 在链表头部添加节点 3list.traverse();  // 打印链表 3->2->1->nillist.push(4);  // 在链表尾部添加节点 4list.traverse();  // 打印链表 3->2->1->4->nillist.push(5);  // 在链表尾部添加节点 5list.traverse();  // 打印链表 3->2->1->4->5->nilcout << list.pop() << endl;  // 删除尾节点,并输出节点数据list.traverse();  // 打印链表 3->2->1->4->nilcout << list.pop() << endl;  // 删除尾节点,并输出节点数据list.traverse();  // 打印链表 3->2->1->nilreturn 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();  // 打印空链表 nillist.add(1);  // 在链表头部添加节点 1list.traverse();  // 打印链表 1->nillist.add(2);  // 在链表头部添加节点 2list.traverse();  // 打印链表 2->1->nillist.add(3);  // 在链表头部添加节点 3list.traverse();  // 打印链表 3->2->1->nillist.push(4);  // 在链表尾部添加节点 4list.traverse();  // 打印链表 3->2->1->4->nillist.push(5);  // 在链表尾部添加节点 5list.traverse();  // 打印链表 3->2->1->4->5->nilcout << list.pop() << endl;  // 删除尾节点,并输出节点数据list.traverse();  // 打印链表 3->2->1->4->nilcout << list.pop() << endl;  // 删除尾节点,并输出节点数据list.traverse();  // 打印链表 3->2->1->nilreturn 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();  // 打印空链表 nillist.add(1);  // 在链表头部添加节点 1list.traverse();  // 打印链表 1->nillist.add(2);  // 在链表头部添加节点 2list.traverse();  // 打印链表 2->1->nillist.add(3);  // 在链表头部添加节点 3list.traverse();  // 打印链表 3->2->1->nillist.push(4);  // 在链表尾部添加节点 4list.traverse();  // 打印链表 3->2->1->4->nillist.push(5);  // 在链表尾部添加节点 5list.traverse();  // 打印链表 3->2->1->4->5->nilSystem.out.println(list.pop());  // 删除尾节点,并输出节点数据list.traverse();  // 打印链表 3->2->1->4->nilSystem.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.headself.head = newNodedef push(self, data):# 在链表尾部添加一个新节点newNode = Node(data)if self.head is None:self.head = newNodeelse:curr = self.headwhile curr.next is not None:curr = curr.nextcurr.next = newNodedef pop(self):# 删除尾节点,并返回该节点的值if self.head is None:return Noneif self.head.next is None:data = self.head.dataself.head = Nonereturn datacurr = self.headwhile curr.next.next is not None:curr = curr.nexttail = curr.nextcurr.next = Nonereturn tail.datadef traverse(self):# 遍历链表,打印每个节点的数据curr = self.headwhile curr is not None:print(curr.data, end='->')curr = curr.nextprint('nil')if __name__ == '__main__':head = LinkedList() # 创建链表head.traverse()     # 遍历空链表head.add(1)         # 在链表头部添加节点 1head.traverse()     # 遍历链表 1->nilhead.add(2)         # 在链表头部添加节点 2head.traverse()     # 遍历链表 2->1->nilhead.add(3)         # 在链表头部添加节点 3head.traverse()     # 遍历链表 3->2->1->nilhead.push(4)        # 在链表尾部添加节点 4head.traverse()     # 遍历链表 3->2->1->4->nilhead.push(5)        # 在链表尾部添加节点 5head.traverse()     # 遍历链表 3->2->1->4->5->nilprint(head.pop())   # 删除尾节点,并输出节点数据head.traverse()     # 打印链表 3->2->1->4->nilprint(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 mainimport "fmt"type Node struct {data intnext *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.headlist.head = newNode
}// 在链表尾部添加一个新节点
func (list *LinkedList) push(value int) {newNode := new(value)if list.head == nil {list.head = newNode} else {curr := list.headfor 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.datalist.head = nilreturn data} else {curr := list.headfor curr.next.next != nil {curr = curr.next}tail := curr.nextcurr.next = nilreturn tail.data}
}// 遍历链表,打印每个节点的数据
func (list *LinkedList) traverse() {curr := list.headfor curr != nil {fmt.Printf("%d->", curr.data)curr = curr.next}fmt.Println("nil")
}func main() {list := LinkedList{}list.traverse()         // 打印空链表 nillist.add(1)             // 在链表头部添加节点 1list.traverse()         // 打印链表 1->nillist.add(2)             // 在链表头部添加节点 2list.traverse()         // 打印链表 2->1->nillist.add(3)             // 在链表头部添加节点 3list.traverse()         // 打印链表 3->2->1->nillist.push(4)            // 在链表尾部添加节点 4list.traverse()         // 打印链表 3->2->1->4->nillist.push(5)            // 在链表尾部添加节点 5list.traverse()         // 打印链表 3->2->1->4->5->nilfmt.Println(list.pop()) // 删除尾节点,并打印数据list.traverse()         // 打印链表 3->2->1->4->nilfmt.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();  // 打印空链表 nillist.add(1);  // 在链表头部添加节点 1list.traverse();  // 打印链表 1->nillist.add(2);  // 在链表头部添加节点 2list.traverse();  // 打印链表 2->1->nillist.add(3);  // 在链表头部添加节点 3list.traverse();  // 打印链表 3->2->1->nillist.push(4);  // 在链表尾部添加节点 4list.traverse();  // 打印链表 3->2->1->4->nillist.push(5);  // 在链表尾部添加节点 5list.traverse();  // 打印链表 3->2->1->4->5->nilprintln!("{}", list.pop().unwrap());  // 删除尾节点,并输出节点数据list.traverse();  // 打印链表 3->2->1->4->nilprintln!("{}", 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();  // 打印空链表 nillist.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.luyixian.cn/news_show_337509.aspx

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

相关文章

sqlSugar应用表值函数

一、新建表值函数 TableIntSplit 二、新建类 var employees _sqlSugarClient.Queryable<Employees>().InnerJoin(_sqlSugarClient.SqlQueryable<TableID>("select * from dbo.TableIntSplit(ids,split)").AddParameters(new { ids "1,2", s…

Spring源码(四)— 创建BeanDefinition

在第一章序言的图示中有提到&#xff0c;Spring中的配置文件都是通过各种的BeanDefinition来进行解析&#xff0c;并且支持不同类型的文件进行扩展。所以在创建完DefaultListableBeanFactory后&#xff0c;会通过BeanDefinition来解析传入的xml配置文件。 loadBeanDefinitions…

【业务功能篇59】Springboot + Spring Security 权限管理 【下篇】

UserDetails接口定义了以下方法&#xff1a; getAuthorities(): 返回用户被授予的权限集合。这个方法返回的是一个集合类型&#xff0c;其中每个元素都是一个GrantedAuthority对象&#xff0c;表示用户被授予的权限。getPassword(): 返回用户的密码。这个方法返回的是一个字符…

打开域名跳转其他网站,官网被黑解决方案(Linux)

某天打开网站&#xff0c;发现进入首页&#xff0c;马上挑战到其他赌博网站。 事不宜迟&#xff0c;不能让客户发现&#xff0c;得马上解决 我的网站跳转到这个域名了 例如网站跳转到 k77.cc 就在你们部署的代码的当前文件夹下面&#xff0c;执行下如下命令 find -type …

【C++】反向迭代器的模拟实现通用(可运用于vector,string,list等模拟容器)

文章目录 前言一、反向迭代器封装&#xff08;reverseiterator&#xff09;1.构造函数1解引用操作.3.->运算符重载4.前置&#xff0c;后置5.前置--&#xff0c;后置--6.不等号运算符重载7.完整代码 二、rbegin&#xff08;&#xff09;以及rend&#xff08;&#xff09;1.rb…

CRM如何进行数据分析?有什么用?

什么是CRM数据分析软件&#xff1f;CRM数据分析软件可以对数据进行挖掘、统计和分析&#xff0c;帮助企业从大量的客户数据中提取有价值的信息&#xff0c;分析数据背后的含义&#xff0c;从而帮助企业更好地运营的一种工具。 1、提高客户满意度 CRM数据分析软件可以通过对客户…

Java的第十五篇文章——网络编程(后期再学一遍)

目录 学习目的 1. 对象的序列化 1.1 ObjectOutputStream 对象的序列化 1.2 ObjectInputStream 对象的反序列化 2. 软件结构 2.1 网络通信协议 2.1.1 TCP/IP协议参考模型 2.1.2 TCP与UDP协议 2.2 网络编程三要素 2.3 端口号 3. InetAddress类 4. Socket 5. TCP网络…

前端调用合约如何避免出现transaction fail

前言&#xff1a; 作为开发&#xff0c;你一定经历过调用合约的时候发现 gas fee 超出限制&#xff0c;但是不知道报了什么错。这个时候一般都是触发了require错误合约校验。对于用户来说他不理解为什么一笔交易会花费如此大的gas&#xff0c;那我们作为开发如何尽量避免这种情…

基于注解手写Spring的IOC(上)

一、思路 先要从当前类出发找到对应包下的所有类文件&#xff0c;再从这些类中筛选出类上有MyComponent注解的类&#xff1b;把它们都装入Map中&#xff0c;同时类属性完成MyValue的赋值操作。 二、具体实现 测试类结构&#xff1a; 测试类&#xff1a;myse、mycontor、BigSt…

【Linux】线程互斥 -- 互斥锁 | 死锁 | 线程安全

引入互斥初识锁互斥量mutex锁原理解析 可重入VS线程安全STL中的容器是否是线程安全的? 死锁 引入 我们写一个多线程同时访问一个全局变量的情况(抢票系统)&#xff0c;看看会出什么bug&#xff1a; // 共享资源&#xff0c; 火车票 int tickets 10000; //新线程执行方法 vo…

用友畅捷通T+服务器数据库中了locked勒索病毒怎么办,如何处理解决

计算机技术的发展&#xff0c;也为网络安全埋下隐患&#xff0c;其中勒索病毒攻击已经成为企业和组织面临的严重威胁之一。作为一款被广泛使用的企业资源管理软件&#xff0c;用友畅捷通T系统也成为黑客攻击的目标之一。近期&#xff0c;我们收到很多企业的求助&#xff0c;公司…

Android Studio 的版本控制Git

Android Studio 的版本控制Git。 Git 是最流行的版本控制工具&#xff0c;本文介绍其在安卓开发环境Android Studio下的使用。 本文参考链接是&#xff1a;https://learntodroid.com/how-to-use-git-and-github-in-android-studio/ 一&#xff1a;Android Studio 中设置Git …

Intel RealSense D455(D400系列) Linux-ROS 安装配置(亲测可用)

硬件&#xff1a;Intel RealSense D455 系统&#xff1a;Ubuntu 18.04 Part_1: 安装librealsense SDK2.0 1.1 注册密钥 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE或者 sudo apt-key adv --keyserver hkp:/…

【RabbitMQ】golang客户端教程1——HelloWorld

一、介绍 本教程假设RabbitMQ已安装并运行在本机上的标准端口&#xff08;5672&#xff09;。如果你使用不同的主机、端口或凭据&#xff0c;则需要调整连接设置。如果你未安装RabbitMQ&#xff0c;可以浏览我上一篇文章Linux系统服务器安装RabbitMQ RabbitMQ是一个消息代理&…

25.10 matlab里面的10中优化方法介绍—— 函数fmincon(matlab程序)

1.简述 关于非线性规划 非线性规划问题是指目标函数或者约束条件中包含非线性函数的规划问题。 前面我们学到的线性规划更多的是理想状况或者说只有在习题中&#xff0c;为了便于我们理解&#xff0c;引导我们进入规划模型的一种情况。相比之下&#xff0c;非线性规划会更加贴近…

联想北京公司研发管理部高级经理周燕龙受邀为第十二届中国PMO大会演讲嘉宾

联想&#xff08;北京&#xff09;有限公司研发管理部高级经理周燕龙先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;PMO如何助力研发。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; PMO在…

gitee使用参考

Git代码托管服务 2.1 常用的Git代码托管服务 gitHub&#xff08; 地址&#xff1a;https://github.com/ &#xff09;是一个面向开源及私有软件项目的托管平台&#xff0c;因为只支持Git 作为唯一的版本库格式进行托管&#xff0c;故名gitHub码云&#xff08;地址&#xff1a;…

Docker安装部署ShardingProxy详细教程

&#x1f680; ShardingSphere &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&…

Go 下载安装教程

1. 下载地址&#xff1a;The Go Programming Language (google.cn) 2. 下载安装包 3. 安装 &#xff08;1&#xff09;下一步 &#xff08;2&#xff09;同意 &#xff08;3&#xff09;修改安装路径&#xff0c;如果不修改&#xff0c;直接下一步 更改后&#xff0c;点击下一…

13个ChatGPT类实用AI工具汇总

在ChatGPT爆火后&#xff0c;各种工具如同雨后春笋一般层出不穷。以下汇总了13种ChatGPT类实用工具&#xff0c;可以帮助学习、教学和科研。 01 / ChatGPT for google/ 一个浏览器插件&#xff0c;可搭配现有的搜索引擎来使用 最大化搜索效率&#xff0c;对搜索体验的提升相…