Java常见数据结构---八大结构

  前言:

数据结构是计算机底层存储、组织数据的方式。是指数据相互之间是以什么方式排列在一起的。 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率 

常见的八大数据结构:

 栈:

思想:

栈是一种数据结构,它遵循后进先出 (LIFO) 原则。这意味着最后添加的元素(称为栈顶元素)将首先被移除。

特点:

  • **简单性和效率:**栈的操作(push、pop、peek)可以在常数时间内完成。
  • **后进先出:**栈的 LIFO 特性使其非常适合需要按添加顺序处理元素的应用。
  • 可以理解为子弹夹一样,先进后出,后出先进

 

 数据进入栈模型的过程称为:压/进栈

  数据出栈模型的过程称为:弹/出栈

代码: 

public class Stack {private int[] arr;private int top;private int capacity;public Stack(int capacity) {this.arr = new int[capacity];this.top = -1;this.capacity = capacity;}public void push(int element) {if (isFull()) {System.out.println("Stack overflow");return;}arr[++top] = element;}public int pop() {if (isEmpty()) {System.out.println("Stack underflow");return -1;}return arr[top--];}public int peek() {if (isEmpty()) {System.out.println("Stack is empty");return -1;}return arr[top];}public boolean isEmpty() {return top == -1;}public boolean isFull() {return top == capacity - 1;}public static void main(String[] args) {Stack stack = new Stack(5);stack.push(1);stack.push(2);stack.push(3);stack.push(4);System.out.println("Top element: " + stack.peek());stack.pop();stack.pop();System.out.println("Top element: " + stack.peek());}
}

过程:

过程解释:

  1. 创建栈:我们创建一个容量为 5 的栈对象。栈是用数组实现的,其中 top 变量跟踪栈顶元素的索引。
  2. 压入元素:push 方法将元素压入栈中。如果栈已满,它会打印一条错误消息。
  3. 弹出元素:pop 方法从栈中移除并返回栈顶元素。如果栈为空,它会打印一条错误消息。
  4. 查看栈顶元素:peek 方法返回栈顶元素,但不将其移除。如果栈为空,它会打印一条错误消息。
  5. 检查栈是否为空:isEmpty 方法检查栈是否为空。
  6. 检查栈是否已满:isFull 方法检查栈是否已满。
  7. 主方法:**在主方法中,我们创建了一个栈对象,压入一些元素,弹出一些元素,并打印栈顶元素。

 最后输出:

Top element: 4

Top element: 2

 

队列:

思想:

队列是一种遵循先进先出 (FIFO) 原则的数据结构。这意味着队列中的第一个添加的元素将首先被移除。与栈恰恰相反,队列两端全开,遵循先进先出,后进后出的原则

特点:

  • 先进先出 (FIFO):队列遵循先进先出原则,这意味着第一个添加的元素将首先被移除。
  • 线性数据结构:队列是一种线性数据结构,这意味着元素按顺序排列。
  • 插入在末尾:新元素总是添加到队列的末尾(也称为尾部)。
  • 删除在头部:元素从队列的头部(也称为前端)移除。
  • 限制访问:队列只允许在头部和尾部进行插入和删除操作。中间元素无法直接访问。
  • 队列大小:队列可以是固定大小的(使用数组实现)或动态大小的(使用链表实现)。
  • 广泛的应用:队列在计算机科学中有广泛的应用,例如消息传递、任务调度、缓冲和广度优先搜索

  

代码: 

import java.util.LinkedList;
import java.util.Queue;public class QueueExample {public static void main(String[] args) {// 创建一个队列Queue<Integer> queue = new LinkedList<>();// 向队列中添加元素queue.add(1);queue.add(2);queue.add(3);queue.add(4);// 从队列中移除元素int removedElement = queue.remove(); // 移除并返回第一个元素// 查看队列中的第一个元素int headElement = queue.peek(); // 返回第一个元素,但不将其移除// 检查队列是否为空boolean isEmpty = queue.isEmpty();// 打印队列中的元素System.out.println("Queue elements: " + queue);// 打印移除的元素System.out.println("Removed element: " + removedElement);// 打印队列头部的元素System.out.println("Head element: " + headElement);// 打印队列是否为空System.out.println("Queue is empty: " + isEmpty);}
}

输出:

Queue elements: [2, 3, 4]
Removed element: 1
Head element: 2
Queue is empty: false

过程: 

  1. 创建队列:我们使用 Java 的 LinkedList 类创建一个队列。LinkedList 实现了 Queue 接口,它提供了队列的基本操作。
  2. 添加元素:add 方法将元素添加到队列的末尾。
  3. 移除元素:remove 方法从队列中移除并返回第一个元素。
  4. 查看队列头部的元素:peek 方法返回队列中的第一个元素,但不将其移除。
  5. 检查队列是否为空:isEmpty 方法检查队列是否为空。

数组:

思想:

数组是一种数据结构,它存储固定数量的相同类型元素的集合。数组中的元素使用索引进行访问,索引从 0 开始。

数组相对其他数据结构相对来说比较简单理解,可以理解为是一组元素,起始值下标从0开始

  1. 查询速度快:查询数据通过地址值和索引定位,查询任意数据耗时相同。 
  2. 删除效率低:要将原始数据删除,同时后面每个数据前移。 

代码: 

public class Array {public static void main(String[] args) {// 声明一个长度为 7 的整型数组int[] arr = {1, 2, 3, 4, 5, 6, 7};// 遍历数组并打印每个元素for (int element : arr) {System.out.println(element);}}
}

 过程:

  1. 声明数组:我们声明一个长度为 7 的整型数组,并使用花括号初始化其元素。
  2. 遍历数组:使用增强 for 循环遍历数组并打印每个元素。

链表:

思想:

链表是一种数据结构,它由一组称为节点的对象组成。每个节点包含一个数据项和指向下一个节点的引用。

在 Java 中,链表使用以下类实现:

  • LinkedList:一个双向链表,允许在列表的任何位置添加和删除元素。
  • ArrayList:一个基于数组的列表,在列表末尾添加和删除元素非常高 

链表中的元素是游离存储的,每个元素节点包含数据值和下一个元素的地址。 

链表是一种增删快、查询慢的模型(对比数组)

 

 代码:

public class LinkedList {public static void main(String[] args) {// 创建一个链表LinkedList<String> list = new LinkedList<>();// 向链表中添加元素list.add("Apple");list.add("Banana");list.add("Orange");// 遍历链表并打印每个元素for (String fruit : list) {System.out.println(fruit);}// 从链表中删除元素list.remove("Banana");// 打印修改后的链表System.out.println("Modified list:");for (String fruit : list) {System.out.println(fruit);}}
}

输出:

Modified list:Apple  Orange

Banana元素已经被链表删除

二叉树:

思想:

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分 [1]。

特点:

 只能有一个根节点,每个节点最多支持2个直接子节点。

节点的度: 节点拥有的子树的个数,二叉树的度不大于2 叶子节点 度为0的节点,也称之为终端结点。

高度:叶子结点的高度为1,叶子结点的父节点高度为2,以此类推,根节点的高度最高。

层:根节点在第一层,以此类推

兄弟节点 :拥有共同父节点的节点互称为兄弟节点

代码:

 

public class BinaryTree {private Node root;public void add(int data) {root = addRecursive(root, data);}private Node addRecursive(Node current, int data) {if (current == null) {return new Node(data);}if (data < current.data) {current.left = addRecursive(current.left, data);} else if (data > current.data) {current.right = addRecursive(current.right, data);}return current;}public boolean contains(int data) {return containsRecursive(root, data);}private boolean containsRecursive(Node current, int data) {if (current == null) {return false;}if (data == current.data) {return true;} else if (data < current.data) {return containsRecursive(current.left, data);} else {return containsRecursive(current.right, data);}}public static void main(String[] args) {BinaryTree tree = new BinaryTree();tree.add(10);tree.add(5);tree.add(15);System.out.println("Contains 5: " + tree.contains(5));System.out.println("Contains 12: " + tree.contains(12));}
}class Node {int data;Node left;Node right;public Node(int data) {this.data = data;}
}

 过程:

  1. 添加元素:add() 方法使用递归将元素添加到二叉树中。它将新元素与当前节点进行比较,并将其添加到左子树或右子树中,具体取决于元素的值。
  2. 查找元素:contains() 方法使用递归在二叉树中查找元素。它将查找值与当前节点进行比较,并根据需要递归地遍历左子树或右子树。
  3. 主方法:main() 方法创建二叉树并向其中添加元素。然后,它调用 contains() 方法来查找树中是否存在特定值。
  4. 输出:Contains 5: true Contains 12: false

二叉查找树:

思想:

二叉搜索树又被称为排序树,它或者是一颗空树,或者是一棵具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

 特点:

1,每一个节点上最多有两个子节点

2,左子树上所有节点的值都小于根节点的值

3,右子树上所有节点的值都大于根节点的值 

目的:提高检索数据的性能。

不同点:

二叉树

  • 每个节点最多有两个子节点(左子节点和右子节点)。
  • 没有排序规则。
  • 可以用于表示各种数据结构,例如堆和哈夫曼树

二叉搜索树(BST)

  • 一个特殊的二叉树,其中每个节点的值都比其左子树的所有值大,并且比其右子树的所有值小。
  • 具有以下性质:
    • 左子树中的所有值都小于根节点的值。
    • 右子树中的所有值都大于根节点的值。
    • 左子树和右子树都是二叉搜索树

区别

二叉搜索树和二叉树之间的主要区别在于排序规则

  • 二叉树没有排序规则,而二叉搜索树中的节点根据其值进行排序

代码: 

public class BinarySearchTree {private Node root;public void add(int data) {root = addRecursive(root, data);}private Node addRecursive(Node current, int data) {if (current == null) {return new Node(data);}if (data < current.data) {current.left = addRecursive(current.left, data);} else if (data > current.data) {current.right = addRecursive(current.right, data);}return current;}public boolean contains(int data) {return containsRecursive(root, data);}private boolean containsRecursive(Node current, int data) {if (current == null) {return false;}if (data == current.data) {return true;} else if (data < current.data) {return containsRecursive(current.left, data);} else {return containsRecursive(current.right, data);}}public static void main(String[] args) {BinarySearchTree tree = new BinarySearchTree();tree.add(10);tree.add(5);tree.add(15);System.out.println("Contains 5: " + tree.contains(5));System.out.println("Contains 12: " + tree.contains(12));}
}class Node {int data;Node left;Node right;public Node(int data) {this.data = data;}
}

 过程:

 

  1. 添加元素:add() 方法使用递归将元素添加到二叉查找树中。它将新元素与当前节点进行比较,并将其添加到左子树或右子树中,具体取决于元素的值。
  2. 查找元素:contains() 方法使用递归在二叉查找树中查找元素。它将查找值与当前节点进行比较,并根据需要递归地遍历左子树或右子树。
  3. 主方法:main() 方法创建二叉查找树并向其中添加元素。然后,它调用 contains() 方法来查找树中是否存在特定值

输出:

Contains 5: true
Contains 12: false

平衡二叉树:

思想:

平衡二叉树是一种特殊的二叉搜索树,其中每个节点的左子树和右子树的高度差至多为 1。这确保了树在很大程度上保持平衡,并且查找、插入和删除操作的时间复杂度为 O(log n),其中 n 是树中的节点数。

 平衡二叉树可以通过使用称为旋转的操作来实现。旋转是重新排列树中节点以维护平衡的一种方法。AVL 树和红黑树使用不同的旋转规则来保持平衡。

平衡二叉树是在满足查找二叉树的大小规则下,让树尽可能矮小,以此提高查数据的性能。  

代码: 

public class AVLTree {private Node root;public void add(int data) {root = addRecursive(root, data);}private Node addRecursive(Node current, int data) {if (current == null) {return new Node(data);}if (data < current.data) {current.left = addRecursive(current.left, data);} else if (data > current.data) {current.right = addRecursive(current.right, data);}updateHeight(current);return balance(current);}private Node balance(Node current) {int balanceFactor = getBalanceFactor(current);if (balanceFactor > 1) {if (getBalanceFactor(current.left) < 0) {current.left = leftRotate(current.left);}return rightRotate(current);} else if (balanceFactor < -1) {if (getBalanceFactor(current.right) > 0) {current.right = rightRotate(current.right);}return leftRotate(current);}return current;}private int getBalanceFactor(Node node) {if (node == null) {return 0;}return height(node.left) - height(node.right);}private int height(Node node) {if (node == null) {return 0;}return node.height;}private void updateHeight(Node node) {node.height = 1 + Math.max(height(node.left), height(node.right));}private Node leftRotate(Node node) {Node newRoot = node.right;node.right = newRoot.left;newRoot.left = node;updateHeight(node);updateHeight(newRoot);return newRoot;}private Node rightRotate(Node node) {Node newRoot = node.left;node.left = newRoot.right;newRoot.right = node;updateHeight(node);updateHeight(newRoot);return newRoot;}public static void main(String[] args) {AVLTree tree = new AVLTree();tree.add(10);tree.add(5);tree.add(15);System.out.println("Inorder traversal of the AVL tree:");inorderTraversal(tree.root);}private static void inorderTraversal(Node node) {if (node != null) {inorderTraversal(node.left);System.out.print(node.data + " ");inorderTraversal(node.right);}}
}class Node {int data;Node left;Node right;int height;public Node(int data) {this.data = data;this.height = 1;}
}

过程: 

  1. 添加元素:add() 方法使用递归将元素添加到 AVL 树中。它将新元素与当前节点进行比较,并将其添加到左子树或右子树中,具体取决于元素的值。添加后,它更新节点的高度并平衡树以保持 AVL 性质。
  2. 平衡树:balance() 方法检查节点的平衡因子并执行必要的旋转以平衡树。
  3. 获取平衡因子:getBalanceFactor() 方法计算节点的平衡因子,它等于左子树的高度减去右子树的高度。
  4. 获取高度:height() 方法计算节点的高度,它等于其子树中最大高度加 1。
  5. 更新高度:updateHeight() 方法更新节点的高度,它等于其子树中最大高度加 1。
  6. 左旋转:leftRotate() 方法执行左旋转操作,它将当前节点的右子树作为新根,并将当前节点作为新根的左子树。
  7. 右旋转:rightRotate() 方法执行右旋转操作,它将当前节点的左子树作为新根,并将当前节点作为新根的右子树。
  8. 主方法:main() 方法创建 AVL 树并向其中添加元素。然后,它打印树的中序遍历以显示树的顺序。

结果: 

Inorder traversal of the AVL tree:
5 10 15
 

红黑树:

规则: 

 每一个节点或是红色的,或者是黑色的,根节点必须是黑色。

如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连的情况)。

对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。

 

当添加的节点为根节点时,直接变成黑色就可以了 

 

 代码:

import java.util.ArrayList;
import java.util.List;public class RedBlackTree {private Node root;public void add(int data) {root = addRecursive(root, data);root.color = Color.BLACK;}private Node addRecursive(Node current, int data) {if (current == null) {return new Node(data);}if (data < current.data) {current.left = addRecursive(current.left, data);} else if (data > current.data) {current.right = addRecursive(current.right, data);}if (isRed(current.left) && isRed(current.right)) {flipColors(current);}if (isRed(current.left) && isRed(current.left.left)) {current = rightRotate(current);}if (isRed(current.right) && isRed(current.right.right)) {current = leftRotate(current);}return current;}private void flipColors(Node node) {node.color = Color.RED;node.left.color = Color.BLACK;node.right.color = Color.BLACK;}private Node rightRotate(Node node) {Node newRoot = node.left;node.left = newRoot.right;newRoot.right = node;newRoot.color = node.color;node.color = Color.RED;return newRoot;}private Node leftRotate(Node node) {Node newRoot = node.right;node.right = newRoot.left;newRoot.left = node;newRoot.color = node.color;node.color = Color.RED;return newRoot;}private boolean isRed(Node node) {return node != null && node.color == Color.RED;}public static void main(String[] args) {RedBlackTree tree = new RedBlackTree();int[] data = {20, 18, 23, 20, 16, 24, 19};for (int value : data) {tree.add(value);}List<Node> redNodes = new ArrayList<>();inorderTraversal(tree.root, redNodes);System.out.println("Red nodes in the Red-Black tree:");for (Node node : redNodes) {System.out.print(node.data + " ");}}private static void inorderTraversal(Node node, List<Node> redNodes) {if (node != null) {inorderTraversal(node.left, redNodes);if (node.color == Color.RED) {redNodes.add(node);}inorderTraversal(node.right, redNodes);}}private enum Color {RED,BLACK}private static class Node {int data;Node left;Node right;Color color;public Node(int data) {this.data = data;this.color = Color.RED;}}
}

步骤:

           20(B)
             /  \
           18(R) 23(R)
          /   /  \
        16(B) 20(R) 24(B)
               /
             19(R)

红色节点R表示,黑节点B表示

 总结:

红黑树不是高度平衡的,它的平衡是通过"红黑规则"进行实现的 

每一个节点或是红色的,或者是黑色的,根节点必须是黑色

如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的;

如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连的情况) 对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。 

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

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

相关文章

大数据项目中的拉链表(hadoop,hive)

缓慢渐变维 拉链表 拉链表&#xff0c;可实现数据快照&#xff0c;可以将历史和最新数据保存在一起 如何实现: 在原始数据增加两个新字段 起始时间&#xff08;有效时间&#xff1a;什么时候导入的数据的时间&#xff09;&#xff0c;结束时间&#xff08;默认的结束时间为99…

运筹系列92:vrp算法包VROOM

1. 介绍 VROOM is an open-source optimization engine written in C20 that aim at providing good solutions to various real-life vehicle routing problems (VRP) within a small computing time. 可以解决如下问题&#xff1a; TSP (travelling salesman problem) CVRP …

九、 个人信息出境标准合同的签署及备案流程是怎样的?

为指导和帮助个人信息处理者规范有序备案个人信息出境标准合同&#xff0c;国家网信办结合此前备案实践经验发布了《标准合同备案指南&#xff08;第二版&#xff09;》&#xff0c;并就个人信息出境标准合同备案的适用范围、备案方式、备案流程和材料以及咨询、举报联系方式等…

产品推荐 | 基于AMD Virtex 7 FPGA VC709 的高速连接功能开发板

01 产品概述 Virtex™ 7 FPGA VC709 连接功能套件是一款速率为 40Gb/s 的高速平台&#xff0c;您可以通过评估和开发连接功能&#xff0c;迅速为包含所有必要软硬件和 IP 核的高带宽和高性能应用提供强大的支持。它包括一个含有 PCI Express Gen 3、Northwest Logic 公司推出的…

4.1 文本相似度(二)

目录 1 文本相似度评估 2 代码 2.1 load_dataset 方法 2.2 AutoTokenizer、AutoModelForSequenceClassification 1 文本相似度评估 对两个文本拼接起来&#xff0c;然后作为一个样本喂给模型&#xff0c;作为一个二分类的任务&#xff1b; 数据处理的方式以及训练的基本流程…

maven .lastUpdated文件作用

现象 有时候我在用maven管理项目时会发现有些依赖报错&#xff0c;这时你可以看一下本地仓库中是否有.lastUpdated文件&#xff0c;也许与它有关。 原因 有这个文件就表示依赖下载过程中发生了错误导致依赖没成功下载&#xff0c;可能是网络原因&#xff0c;也有可能是远程…

平面设计基础指南:从零开始的学习之旅!

平面设计师主要做什么&#xff1f; 平面设计师通过创建视觉概念来传达信息。他们创造了从海报和广告牌到包装、标志和营销材料的所有内容&#xff0c;并通过使用形状、颜色、排版、图像和其他元素向观众传达了他们的想法。平面设计师可以在内部工作&#xff0c;专门为品牌创建…

Mac安装jadx

1、使用命令brew安装 : brew install jadx 输入完命令,等待安装完毕 备注&#xff08;关于Homebrew &#xff09;&#xff1a; Homebrew 是 MacOS 下的包管理工具&#xff0c;类似 apt-get/apt 之于 Linux&#xff0c;yum 之于 CentOS。如果一款软件发布时支持了 homebrew 安…

mac定时任务、自启动任务

https://quail.ink/mynotes/p/mac-startup-configuration-detailed-explanation <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.d…

【2024年5月备考新增】】 考前篇(2)《官方平台 - 考生模拟练习平台常用操作(一)》

软考考生常用操作说明 说明:模拟作答系统是旨在让考生熟悉计算机化考试环境和作答方式,模拟作答不保存考生作答 历史记录。考试题型、题量、分值、界面及文字内容以正式考试答题系统为准。 1 如何标记试题、切换试题 2 简答题如何查看历史记录、切换输入法 3 选做题,已作答…

游戏找不到steam_api64.dll如何解决,介绍5种简单有效的方法

面对“找不到steam_api64.dll&#xff0c;无法继续执行代码”的问题&#xff0c;许多游戏玩家或软件使用者可能会感到手足无措。这个错误提示意味着你的计算机系统在尝试运行某个游戏或应用程序时&#xff0c;无法定位到一个至关重要的动态链接库文件——steam_api64.dll&#…

《深入Linux内核架构》第3章 内存管理(6)

目录 3.5.7 内核中不连续页的分配 3.5.8 内核映射 本专栏文章将有70篇左右&#xff0c;欢迎关注&#xff0c;订阅后续文章。 本节讲解vmalloc, vmap&#xff0c;kmap原理。 3.5.7 内核中不连续页的分配 kmalloc函数&#xff1a;分配物理地址和虚拟地址都连续的内存。 kmall…

Selenium + Pytest自动化测试框架实战(上)

前言 今天呢笔者想和大家来聊聊selenium自动化 pytest测试框架&#xff0c;在这篇文章里你需要知道一定的python基础——至少明白类与对象&#xff0c;封装继承&#xff1b;一定的selenium基础。这篇文章不会selenium&#xff0c;不会的可以自己去看selenium中文翻译网哟。 一…

六西格玛管理培训公司:事业进阶的充电站,助你冲破职场天花板!

六西格玛&#xff0c;源于制造业&#xff0c;却不仅仅局限于制造业。它是一种以数据为基础、以顾客为中心、以流程优化为手段的全面质量管理方法。通过六西格玛管理&#xff0c;企业可以系统性地识别并解决运营过程中的问题&#xff0c;提高产品和服务的质量&#xff0c;降低成…

导航app为什么知道还有几秒变绿灯?

在使用地图导航app行驶至信号灯的交叉路口时&#xff0c;这些应用程序会贴心地告知用户距信号灯变化还有多少秒&#xff0c;无论是即将转为绿灯还是红灯。这一智能化提示不仅使得驾驶员能适时做好起步或刹车的准备&#xff0c;有效缓解了因等待时间不确定而产生的焦虑情绪&…

GBPC2510-ASEMI工业电源专用GBPC2510

编辑&#xff1a;ll GBPC2510-ASEMI工业电源专用GBPC2510 型号&#xff1a;GBPC2510 品牌&#xff1a;ASEMI 封装&#xff1a;GBPC-4 最大重复峰值反向电压&#xff1a;1000V 最大正向平均整流电流(Vdss)&#xff1a;25A 功率(Pd)&#xff1a;中小功率 芯片个数&#x…

分布式锁之RedissonLock

什么是Redisson&#xff1f; 俗话说他就是看门狗&#xff0c;看门狗机制是一种用于保持Redis连接活跃性的方法&#xff0c;通常用于分布式锁的场景。看门狗的工作原理是&#xff1a;当客户端获取到锁之后&#xff0c;会对Redis中的一个特定的键设置一个有限的过期时间&#xff…

[附源码]传世手游_玲珑传世_GM_安卓搭建教程

本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#xff0c;踩过的坑都给你们填上了。 如果你是小白也没…

了解进程和线程

一、进程和线程 类比&#xff1a; 一个工厂&#xff0c;至少有一个车间&#xff0c;一个车间中至少有一个工人&#xff0c;最终是工人在工作。 一个程序&#xff0c;至少有一个进程&#xff0c;一个进程中至少有一个线程&#xff0c;最终是线程在工作。 进程&#xff1a;是计…

乡村振兴与乡村旅游深度融合:依托乡村自然和文化资源,发展乡村旅游产业,促进农民增收致富,打造特色美丽乡村

目录 一、引言 二、乡村振兴与乡村旅游的内在联系 三、依托乡村自然和文化资源发展乡村旅游产业 &#xff08;一&#xff09;挖掘乡村自然资源优势&#xff0c;打造特色旅游品牌 &#xff08;二&#xff09;挖掘乡村文化资源内涵&#xff0c;丰富旅游活动内容 四、促进农…