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

news2024/9/23 17:12:35

单链表

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

单链表的主要操作包括:

  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.coloradmin.cn/o/811007.html

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

相关文章

【指针二:穿越编程边界的超能力】

本章重点 5. 函数指针 6. 函数指针数组 7. 指向函数指针数组的指针 8. 回调函数 9. 指针和数组面试题的解析 五、函数指针 首先看一段代码&#xff1a; 输出的是两个地址相同&#xff0c;这两个相同的地址都是 test 函数的地址。 那我们的函数的地址要想保存起来&#xff0c;怎…

LeetCode63. 不同路径 II

63. 不同路径 II 文章目录 [63. 不同路径 II](https://leetcode.cn/problems/unique-paths-ii/)一、题目二、题解方法一&#xff1a;二维数组动态规划方法二&#xff1a;一维数组动态规划 一、题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “…

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

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

rtthread的idle线程不应该长时间堵塞

RT-Thread是一个实时嵌入式操作系统&#xff0c;它的空闲线程&#xff08;Idle Thread&#xff09;是在系统中没有其他任务需要执行时运行的线程。空闲线程通常用于执行一些低优先级的任务或者进行系统的休眠等操作。 RT-Thread的空闲线程不能在线程中堵塞的原因是为了确保系统…

将多张图片拼接成图像矩阵图

用Python实现将12张图片排列成n*m的图像矩阵图 目录 引言环境准备代码实现效果演示总结 引言 在图像处理和图像展示的应用中&#xff0c;将多张图片排列成一个图像矩阵图是一个常见的需求。本博客介绍如何使用Python实现将12张图片排列成n*m的图像矩阵图。 环境准备 为了实…

【动态规划刷题 2】不同路径不同路径 II

不同路径 62 . 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的…

iPhone 安装 iOS 17公测版(Public Beta)

文章目录 步骤1. 备份iPhone资料步骤2. 申请iOS 17 公测Beta 资格步骤3. 下载iOS 16 Beta 公测描述档步骤4. 选择iOS 17 Beta 公测描述档更新项目步骤5. 升级iOS 17 Public Beta 公开测试版 苹果已经开始向大众释出首个iOS 17 公开测试版/ 公测版( iOS 17 Public Beta)&#xf…

【C++】类和对象 - 上

目录 1. 面向过程和面向对象初步认识2. 类的引入3. 类的定义4. 类的访问限定符及封装4.1 访问限定符4.2 封装 5. 类的作用域6. 类的实例化7. 类对象模型7.1 如何计算类的大小7.2 类对象的存储方式猜测7.3 结构体内存对齐规则 8. this指针8.1 引出8.2 this指针的特性 总结 1. 面…

ES查看集群信息(健康状态、分片、索引等)

1、查看集群状态使用频率最高的方法 http://192.168.1.101:9200/ 注意&#xff1a;不同环境的ip不同 一般我们通过这个方式来验证ES服务器是否启动成功。 2、_cat/health 查看集群健康状态 [rootCENTOS01 ~]# curl http://192.168.1.101:9200/_cat/health?v epoch tim…

Spring Data【Spring Data Redis、Spring Data ElasticSearch】(二)-全面详解(学习总结---从入门到深化)

目录 四、 Spring Data Redis 五、 Spring Data ElasticSearch 四、 Spring Data Redis Redis 是一个基于内存的数据结构存储系统&#xff0c;它可以用作数据库或者缓存。它支持多种 类型的数据结构&#xff0c;这些数据结构类型分别为 String&#xff08;字符串&#xff09…

0基础系列C++教程 从0开始 第四课

目录 来学习新的内容吧 1 输入 第四课课后习题1&#xff1a; 2 变量 怎么定义变量&#xff1f; 定义变量 第四课课后习题2&#xff1a; 来学习新的内容吧 1 输入 C中既然有了输出 那必然有输入 这时 我们就要用到 cin 函数啦 cin 用法与cout 相似 但却有一个差异 co…

Vue(十八):echarts地图省市区联动

效果 数据来源 https://datav.aliyun.com/portal/school/atlas/area_selector 接口请求地址 https://geo.datav.aliyun.com/areas_v3/bound/geojson?code100000_full 源码 样式 .map {width: 1000px;height: 700px; }布局 <template><div class"map">…

linux -网络编程-多线程并发服务器

目录 1.三次握手和四次挥手 2 滑动窗口 3 函数封装思想 4 高并发服务器 学习目标&#xff1a; 掌握三次握手建立连接过程掌握四次握手关闭连接的过程掌握滑动窗口的概念掌握错误处理函数封装实现多进程并发服务器实现多线程并发服务器 1.三次握手和四次挥手 思考: 为什么…

linux centos7 安装java17

删除旧版本的java或者说是自带的&#xff0c;免得干扰 查找java rpm -qa|grep java java-1.8.0-openjdk-1.8.0.262.b10-1.el7.x86_64 javapackages-tools-3.4.1-11.el7.noarch tzdata-java-2020a-1.el7.noarch python-javapackages-3.4.1-11.el7.noarch java-1.8.0-open…

力扣热门100题之矩阵置0【中等】

题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 示例 2&#xff…

❤️创意网页:萌翻少女心的果冻泡泡 - 创造生动有趣的视觉效果

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;简单好用又好看&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;欢迎踏入…

计算机网络(Computer Networks)基础

本篇介绍计算机网络的基础知识。 文章目录 1. 计算机网络历史2. 以太网" (Ethernet)2.1 以太网" (Ethernet)的简单形式及概念2.2 指数退避解决冲突问题2.3 利用交换机减少同一载体中设备2.4 互联网&#xff08;The Internet&#xff09;2.5 路由(routing)2.6 数据包…

渗透测试基础知识(1)

渗透基础知识一 一、Web架构1、了解Web2、Web技术架构3、Web客户端技术4、Web服务端组成5、动态网站工作过程6、后端存储 二、HTTP协议1、HTTP协议解析2、HTTP协议3、http1.1与http2.0的区别4、HTTP协议 三、HTTP请求1、发起HTTP请求2、HTTP响应与请求-HTTP请求3、HTTP响应与请…

typedef对类型的重命名

typedef 重命名的类型 重命名后的类型名 typedef重命名函数指针类型时的特别写法 正确的重命名函数指针类型的方式 运用&#xff1a; 用typedef简化下面这个代码 简化后&#xff1a;

【C语言day11】

数据类型的等级从低到高如下&#xff1a;char int long float double运算的时候是从低转到高的&#xff0c;表达式的类型会自动提升或者转换为参与表达式求值的最上级类型 #include <stdio.h> int main() {int x -1;unsigned int y 2;if (x > y){printf("x is …