并查集介绍和常用模板
并查集介绍和常用模板
前言:
并查集(Union-find set 也叫Disjoint Sets)是图论里面一种用来判断节点之间是否连通的数据结构,学会使用它可以处理一些跟节点连通性的问题。它有两个很重要的方法:
-
Find(x):查找x的父元素
-
Union(x,y):将x,y两个对应的集合合并到一起
接下来我们先看一个例子,看看怎么判断节点之间是否相连,怎么把两个集合合并到一起:
先看第一个问题,怎么判断两个节点是否相连?
在上面这张图里面我们肉眼可以看到(0,1,2)是连在一起,(3,4)是连在一起,(5)是单独存在的,这也是前置客观存在的条件。
那么我们怎么判断0和3是不是连到一起了呢?思路是这样,我们把这三块看成是三个团队,(0,1,2)是一个团队,队长是0,(3,4)是一个团队,队长是3,(5)是一个团队,队长是5。判断逻辑是,两个元素的队长是相同的,就认为在一个团队里面。所以更加计算机化的语言描述是,三个集合,每个集合都有一个根节点,如果根节点是相同的,就是在一个集合里面。因此你要想到,我们需要存储每个节点对应的根节点,这样才能判断出两个节点是否在同一个集合内。
再看第二个问题,怎么将两个集合合并?
看过问题一后,你可能就已经有一些思路了,既然只要是根节点相同就是同一个集合,判断是否相连,那么我是不是合并两个集合的时候只要根节点改成同一个就行了?没错,就是这样。合并的时候就把某个集合的根节点改成另外一个集合的根节点就行了。这里引申出一个问题,应该把哪个集合的根节点修改掉?后面我们讲到按照秩来合并集合的时候会讲到,一般情况,随便用哪个集合的根节点都可以。
并查集常用模板:
1.QuickFind:
我们直接快进到代码部分,因为有了前面的例子的铺垫,再来讲代码应该就比较好理解了,说明我都放到代码的注释里面了。
public class UnionFind1 {// 首先我们创建了一个数组 用来保存每个元素的根节点public int root[];// 然后我们根据元素的数量 初始化数组,数组的下标就是节点,数组的值就是元素i的根节点,一开始每个元素的根节点都是自己public UnionFind1(int size) {root = new int[size];for (int i = 0; i < size; i++) {root[i] = i;}}// find找根节点,直接返回x对应的根节点root[x]public int find(int x) {return root[x];}// union合并两个元素x,ypublic void union(int x, int y) {// 先找到各自的根节点 一开始都是元素自己int rootX = find(x);int rootY = find(y);if (rootX != rootY) {// 因为两个根节点不一样 所以我们随便取一个元素的根节点作为新的根节点// 这里取的rootX为新的根节点,然后把原来所有根节点是rootY的都修改为rootXfor (int i = 0; i < root.length; i++) {if (root[i] == rootY) {root[i] = rootX;}}}};// 判断两个元素是否相连 其实就是判断根节点是否相同 是对find()的一种运用public boolean connected(int x, int y) {return find(x) == find(y);}public static void main(String[] args) throws Exception {// 下面的例子就更好理解了,我们先初始化并查集一共6个元素,就是上面图中的元素// 在图中的连接情况 把0,1,2连起来,3,4连起来,并用connected()测试下元素的连通性// 最后我们把元素5加入到1的集合中,测试下2和5的连通性,发现确实2和5也相连了,程序测试完成。UnionFind1 uf = new UnionFind1(6);// 0-1-2 3-4 5uf.union(0, 1);uf.union(0, 2);uf.union(3, 4);// trueSystem.out.println(uf.connected(1, 2));// falseSystem.out.println(uf.connected(1, 3));// falseSystem.out.println(uf.connected(4, 5));// 0-1-2 3-4 5uf.union(1, 5);// trueSystem.out.println(uf.connected(2, 5));}
}
这个模板为什么要叫QuickFind呢?因为这个模板的find方法比较快,是O(1)的时间复杂度,但是union方法就比较麻烦得元素都遍历一遍,复杂度是O(N)
2.QuickUnion
quickUnion主要是union的操作比较快,直接将x,y元素中任意一个元素变成另外一个元素的爸爸,操作是O(1),但是要找根节点的时候就毕竟慢,得一直往上找直到是根节点为止。
public class UnionFind2 {public int[] root;public UnionFind2(int size) {root = new int[size];for (int i = 0; i < size; i++) {root[i] = i;}}public int find(int x) {while (root[x] != x) {return root[x] = find(root[x]);}return x;}public void union(int x, int y) {int xRoot = find(x);int yRoot = find(y);if (xRoot != yRoot) {root[yRoot] = xRoot;}}public boolean connected(int x, int y) {return find(x) == find(y);}public static void main(String[] args) throws Exception {// 下面的例子就更好理解了,我们先初始化并查集一共6个元素,就是上面图中的元素// 在图中的连接情况 把0,1,2连起来,3,4连起来,并用connected()测试下元素的连通性// 最后我们把元素5加入到1的集合中,测试下2和5的连通性,发现确实2和5也相连了,程序测试完成。UnionFind2 uf = new UnionFind2(6);// 0-1-2 3-4 5uf.union(0, 1);uf.union(0, 2);uf.union(3, 4);// trueSystem.out.println(uf.connected(1, 2));// falseSystem.out.println(uf.connected(1, 3));// falseSystem.out.println(uf.connected(4, 5));// 0-1-2 3-4 5uf.union(1, 5);// trueSystem.out.println(uf.connected(2, 5));}
}
3.按秩合并的QuickUnion
public class UnionFind3 {// 在QuickUnion的基础上增加了rank数组来记录int root[];int rank[];// 初始化的时候rank默认都是1public UnionFind3(int size) {root = new int[size];rank = new int[size];for (int i = 0; i < size; i++) {root[i] = i;rank[i] = 1;}}public int find(int x) {while (x != root[x]) {x = root[x];}return x;}// 如果两个元素的秩相同就随机取一个元素为秩更大的 否则就是谁的秩大 谁就是爸爸public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX != rootY) {if (rank[rootX] > rank[rootY]) {root[rootY] = rootX;} else if (rank[rootX] < rank[rootY]) {root[rootX] = rootY;} else {root[rootY] = rootX;rank[rootX] += 1;}}}public boolean connected(int x, int y) {return find(x) == find(y);}public static void main(String[] args) throws Exception {// 下面的例子就更好理解了,我们先初始化并查集一共6个元素,就是上面图中的元素// 在图中的连接情况 把0,1,2连起来,3,4连起来,并用connected()测试下元素的连通性// 最后我们把元素5加入到1的集合中,测试下2和5的连通性,发现确实2和5也相连了,程序测试完成。UnionFind3 uf = new UnionFind3(6);// 0-1-2 3-4 5uf.union(0, 1);uf.union(0, 2);uf.union(3, 4);// trueSystem.out.println(uf.connected(1, 2));// falseSystem.out.println(uf.connected(1, 3));// falseSystem.out.println(uf.connected(4, 5));// 0-1-2 3-4 5uf.union(1, 5);// trueSystem.out.println(uf.connected(2, 5));}
}
4.路径压缩的QuickUnion
public class UnionFind4 {int root[];public UnionFind4(int size) {root = new int[size];for (int i = 0; i < size; i++) {root[i] = i;}}// 优化点在这里 再查找父节点的同时会把根节点赋值给递归过程的其他元素public int find(int x) {if (x == root[x]) {return x;}return root[x] = find(root[x]);}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX != rootY) {root[rootY] = rootX;}};public boolean connected(int x, int y) {return find(x) == find(y);}public static void main(String[] args) throws Exception {// 下面的例子就更好理解了,我们先初始化并查集一共6个元素,就是上面图中的元素// 在图中的连接情况 把0,1,2连起来,3,4连起来,并用connected()测试下元素的连通性// 最后我们把元素5加入到1的集合中,测试下2和5的连通性,发现确实2和5也相连了,程序测试完成。UnionFind4 uf = new UnionFind4(6);// 0-1-2 3-4 5uf.union(0, 1);uf.union(0, 2);uf.union(3, 4);// trueSystem.out.println(uf.connected(1, 2));// falseSystem.out.println(uf.connected(1, 3));// falseSystem.out.println(uf.connected(4, 5));// 0-1-2 3-4 5uf.union(1, 5);// trueSystem.out.println(uf.connected(2, 5));}
}
5.按秩Union并且路径压缩:
这个没有太多要说的,就是3,4模板和合并,可以同时解决查询慢和防止并查集变成链表的情况。
public class UnionFind5 {private int[] root;private int[] rank;public UnionFind5(int size) {root = new int[size];rank = new int[size];for (int i = 0; i < size; i++) {root[i] = i;rank[i] = 1;}}public int find(int x) {if (x == root[x]) {return x;}return root[x] = find(root[x]);}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX != rootY) {if (rank[rootX] > rank[rootY]) {root[rootY] = rootX;} else if (rank[rootX] < rank[rootY]) {root[rootX] = rootY;} else {root[rootY] = rootX;rank[rootX] += 1;}}}public boolean connected(int x, int y) {return find(x) == find(y);}public static void main(String[] args) throws Exception {// 下面的例子就更好理解了,我们先初始化并查集一共6个元素,就是上面图中的元素// 在图中的连接情况 把0,1,2连起来,3,4连起来,并用connected()测试下元素的连通性// 最后我们把元素5加入到1的集合中,测试下2和5的连通性,发现确实2和5也相连了,程序测试完成。UnionFind5 uf = new UnionFind5(6);// 0-1-2 3-4 5uf.union(0, 1);uf.union(0, 2);uf.union(3, 4);// trueSystem.out.println(uf.connected(1, 2));// falseSystem.out.println(uf.connected(1, 3));// falseSystem.out.println(uf.connected(4, 5));// 0-1-2 3-4 5uf.union(1, 5);// trueSystem.out.println(uf.connected(2, 5));}
}
用并查集解决问题:
这里我们来看一道用并查集解决的算法题leetcode-200岛屿数量
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。示例 1:输入:grid = [["1","1","1","1","0"],["1","1","0","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]
]
输出:1
示例 2:输入:grid = [["1","1","0","0","0"],["1","1","0","0","0"],["0","0","1","0","0"],["0","0","0","1","1"]
]
输出:3提示:m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j] 的值为 '0' 或 '1'
这道题目可以用bfs/dfs解决,也可以用并查集,因为我们刚学习完并查集,所以就学以致用。
解题思路:
遍历整个图,将是邻近的岛屿元素全部用并查集连起来,也就是把1连起来,最后统计parent有多少个,就是有多少岛屿(不过这道题m*n比较大,遍历会超时)。当然我们也可以在union的时候判断出岛屿的数量,最后直接返回。
class UnionFind {public int root[];// 用来统计最后有多少个岛屿int num;public UnionFind(char[][] grid) {int row = grid.length;int col = grid[0].length;root = new int[row * col];for (int r = 0; r < row; r++) {for (int c = 0; c < col; c++) {if (grid[r][c] == '1') {// 如果是岛屿的话 num就增加num++;// 将二维坐标准换为一维的root[r * col + c] = r * col + c;}}}}// 优化点在这里 再查找父节点的同时会把根节点赋值给递归过程的其他元素public int find(int x) {if (x == root[x]) {return x;}return root[x] = find(root[x]);}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX != rootY) {root[rootY] = rootX;num--;}}}public int numIslands(char[][] grid) {int row = grid.length;int col = grid[0].length;UnionFind uf = new UnionFind(grid);int sea = 0;for (int r = 0; r < row; r++) {for (int c = 0; c < col; c++) {if (grid[r][c] == '1') {// 处理完之后 赋值为另外一个值 这样下次就不会重复遍历到这个值grid[r][c] = '0';if (r - 1 >= 0 && grid[r - 1][c] == '1') {uf.union(r * col + c, (r - 1) * col + c);}if (r + 1 < row && grid[r + 1][c] == '1') {uf.union(r * col + c, (r + 1) * col + c);}if (c - 1 >= 0 && grid[r][c - 1] == '1') {uf.union(r * col + c, r * col + c - 1);}if (c + 1 < col && grid[r][c + 1] == '1') {uf.union(r * col + c, r * col + c + 1);}}}}return uf.num;}@Testpublic void test1() {Assert.assertEquals(3, numIslands(new char[][]{new char[]{'1', '1', '0', '0', '0'},new char[]{'1', '1', '0', '0', '0'},new char[]{'0', '0', '1', '0', '0'},new char[]{'0', '0', '0', '1', '1'}}));Assert.assertEquals(1, numIslands(new char[][]{new char[]{'1', '1', '1'},new char[]{'0', '1', '0'},new char[]{'1', '1', '1'},}));}
相关文章:
并查集介绍和常用模板
并查集介绍和常用模板 前言: 并查集(Union-find set 也叫Disjoint Sets)是图论里面一种用来判断节点之间是否连通的数据结构,学会使用它可以处理一些跟节点连通性的问题。它有两个很重要的方法: Find(x):…...
解决deepspeed框架的bug:不保存调度器状态,模型训练重启时学习率从头开始
deepspeed存在一个bug,即在训练时不保存调度器状态,因此如果训练中断后再重新开始训练,调度器还是会从头开始而不是接着上一个checkpoint的调度器状态来训练。这个bug在deepspeed的github中也有其他人提出:https://github.com/mic…...
Linux ipc通信(消息对列)
前言:消息队列也是linux开发ipc机制中较为重要的一个进程间通信机制。 1.系统创建或获取消息对列 int msgget(key_t key, int mode); 创建消息队列,或者获取消息队列。 参数: key - 使用ftok()获取到的key mode - IPC_CREAT|0666 返回&…...
【计算机网络】 ARP协议和DNS协议
文章目录 数据包在传输过程中的变化过程单播组播和广播ARP协议ARP代理免费ARP路由数据转发过程DNS协议 数据包在传输过程中的变化过程 在说ARP和DNS之前,我们需要知道数据包在传输过程的变化过程 从图片中可以看到,发送方的原数据最开始是在应用层&…...
【逐步剖C++】-第一章-C++类和对象(上)
前言:本文主要介绍有关C入门需掌握的基础知识,包括但不限于以下几个方面,这里是文章导图: 本文较长,内容较多,大家可以根据需求跳转到自己感兴趣的部分,希望能对读者有一些帮助 那么本文也主要…...
索尼 toio™ 应用创意开发征文|探索创新的玩乐世界——索尼 toio™
导语: 在技术的不断进步和发展中,玩具也逐渐融入了智能化的潮流。索尼 toio™作为一款前沿的智能玩具,给孩子和成人带来了全新的游戏体验。本文将介绍索尼 toio™的特点、功能和应用场景,让读者了解这个令人兴奋的创新产品。 1. 了…...
企业架构LNMP学习笔记23
1、隐藏版本号: Nginx对外提供服务,为了避免被针对某个版本的漏洞进行攻击。经常做法是隐藏掉软件的版本信息,提供一定的安全性。 server_tokens off; https和CA: 1)基于SSL CA证书的公私钥的安全性。 CA是需要生成…...
第六章 图 五、图的深度优先遍历(DFS算法)
目录 一、定义 深度优先遍历通常用于解决以下问题: 深度优先遍历算法具有以下优点: 深度优先遍历算法的一个缺点是: 二、代码 空间复杂度: 时间复杂度: 邻接矩阵存储: 邻接表存储: 三、…...
React 中的 useLayoutEffect 钩子函数
useLayoutEffect钩子函数的作用跟useEffect钩子函数的作用一样,它们的不同主要是在于: 1、useEffect钩子函数是异步的,因为此函数在执行的时候是先计算出所有的 Dom 节点的改变后再将对应的 Dom 节点渲染到屏幕上,然而在 useEffe…...
upload-labs1-21关文件上传通关手册
upload-labs文件上传漏洞靶场 目录 upload-labs文件上传漏洞靶场第一关pass-01:第二关Pass-02第三关pass-03:第四关pass-04:第五关pass-05:第六关pass-06:第七关Pass-07第八关Pass-08第九关Pass-09第十关Pass-10第十一…...
MATLAB遗传算法求解生鲜货损制冷时间窗碳排放多成本车辆路径规划问题
MATLAB遗传算法求解生鲜货损制冷时间窗碳排放多成本车辆路径规划问题实例 1、问题描述 已知配送中心和需求门店的地理位置,并且已经获得各个门店的需求量。关于送货时间的要求,门店都有规定的时间窗,对于超过规定时间窗外的配送时间会产生相应的惩罚成本。为保持生鲜农产品的…...
界面控件DevExpress .NET应用安全 Web API v23.1亮点:支持Swagger模式
DevExpress拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。 DevExpress 今年第一个重要版本v23.1日前已正式发布了,该版本拥有众多新产品和数十…...
SpringMVC之CRUD------增删改查
目录 前言 配置文件 pom.xml文件 web.xml文件 spring-context.xml spring-mvc.xml spring-MyBatis.xml jdbc.properties数据库配置文件 generatorConfig.xml log4j2日志文件 后台 PageBaen.java PageTag.java 切面类 biz层 定义一个接口 再写一个实现类 …...
微信小程序开发教学系列(4)- 抖音小程序组件开发
章节四:抖音小程序组件开发 在本章中,我们将深入探讨抖音小程序的组件开发。组件是抖音小程序中的基本构建块,它们负责展示数据和与用户交互。了解组件的开发方法和使用技巧是进行抖音小程序开发的重要一步。 4.1 抖音小程序的基本组件 抖…...
RabbitMQ反序列化失败:Failed to convert message
🎈 1 参考文档 RabbitMQ消费消息坑:failed to convert serialized Message content | jiuchengi-cnblogs 🔍2 问题描述 org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Failed to convert messageat org.sprin…...
CTFSHOW 年CTF
1.除夕 php的弱类型,用小数点绕过 这里后面直接加字母不行 2.初三 error_reporting(0); extract($_GET); include "flag.php"; highlight_file(__FILE__); 这里通过extract将get的参数导入为了变量 $_function($__,$___){return $__$___?$___:$__; }; …...
肖sir__设计测试用例方法之状态迁移法05_(黑盒测试)
设计测试用例方法之状态迁移法 一、状态迁移图 定义:通过描绘系统的状态及引起系统状态转换的事件,来表示系统的行为 案例: (1) 订机票案例1: l向航空公司打电话预定机票—>此时机票信息处于“完成”状…...
无涯教程-JavaScript - IMPRODUCT函数
描述 IMPRODUCT函数以x yi或x yj文本格式返回1到255个复数的乘积。两个复数的乘积为- $$(A BI)(C DI)(AC-BD)(A B)1 $$ 语法 IMPRODUCT (inumber1, [inumber2] ...)争论 Argument描述Required/OptionalInumber11 to 255 complex numbers to multiply.Required[inumbe…...
yapi以及gitlab的容器化部署
yapi部署: https://blog.csdn.net/Chimengmeng/article/details/132074922 gitlab部署 使用docker-compose.yml version: 3 services: web: image: twang2218/gitlab-ce-zh:10.5 restart: always hostname: 192.168.xx.xx environm…...
TCP、UDP 协议的区别,各自的应用场景
分析&回答 TCP 传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能&…...
C高级 DAY3
一、shell中的变量 shell本身是擅长运行指令,是一种弱数据类型语言 它与c语言中定义变量有所不同 C中: 存储类型 数据类型 变量名;shell中: 变量变量的值 ----->如果变量的值中间没有空格直接使用 变量变量的值 ----->变量…...
Linux CentOS7命令及命令行
Linux CentOS7中命令及命令行是非常重要的概念。对大多数初学者来说是既熟悉又了解甚少。本文初步讨论这方面的内容,与同行者交流。 一、命令 命令又称为指令,(英语命令 command,可用简写cmd表示),在终端…...
【C++入门到精通】C++入门 ——搜索二叉树(二叉树进阶)
阅读导航 前言一、搜索二叉树简介1. 概念2. 基本操作⭕搜索操作🍪搜索操作基本代码(非递归) ⭕插入操作🍪插入操作基本代码(非递归) ⭕删除操作🍪删除操作基本代码(非递归࿰…...
学成在线-网站搭建
文章目录 代码素材来自b站pink老师 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>学成在线首…...
stm32同芯片但不同flash工程更换Device出现报错
目录 1. 问题描述2. 解决方案 1. 问题描述 stm32同芯片但不同flash工程更换Device出现报错 2. 解决方案 更换Device,我是从ZE换为C8: 把这个从HD更换为MD 解决!...
Element UI实现每次只弹出一个Message消息提示
前言 在开发Web应用程序时,我们经常需要使用消息提示来向用户展示重要信息。Element UI提供了一个方便易用的组件——Message,可以用于显示各种类型的消息提示。 然而,默认情况下,当多个消息提示同时触发时,它们会依…...
「网页开发|前端开发|Vue」04 快速掌握开发网站需要的Vue基础知识
本文主要介绍使用Vue进行前端开发的一些必备知识,比如:Vue应用实例,Vue的组件概念,模板语言和模板语法,计算属性,路由配置等等。 文章目录 本系列前文传送门前言一、Vue实例:项目入口二、模板语…...
解决Redis分布式锁主从架构锁失效问题的终极方案 含面试题
面试题分享 2023最新面试合集链接 2023大厂面试题PDF 面试题PDF版本 java、python面试题 项目实战:AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 史上最全文档AI绘画stab…...
建站系列(三)--- 网络协议
目录 相关系列文章前言一、定义二、术语简介三、协议的组成要素四、网络层次划分五、常见网络协议划分六、常用协议介绍(一)TCP/IP(二)HTTP协议(超文本传输协议)(三)SSH协议 相关系列…...
jetson orin nx无显示器启动
sudo apt-get install xserver-xorg-core-hwe-18.04 sudo apt-get install xserver-xorg-video-dummy在 /usr/share/X11/xorg.conf.d/ 中添加 xorg.conf 文件。 Section "Monitor"Identifier "Monitor0"HorizSync 28.0-80.0VertRefresh 48.0-75.0Modeline…...
咸宁网站建设/黑帽seo什么意思
如题: m1的mac总是上网卡的一批,微信正常,但是浏览器(所有浏览器)总是没有网络,弄个网页就是打不开,最后试了试改DNS瞬间有用。 点击WIFI图标 > 网络偏好设置... > 高级... > DNS 将…...
兰州手机网站制作公司/北京seo专业团队
基于springboot在线投票系统 摘 要 随着全球Internet的迅猛发展和计算机应用的普及,特别是近几年无线网络的广阔覆盖以及无线终端设备的爆炸式增长,使得人们能够随时随地的访问网络,以获取最新信息、参与网络活动、和他人在线互动。为了能及时…...
网站流量来源/企业管理软件管理系统
jQuery UI是一套非常好用的jQuery Tools库,目前已经发布的最新版本是1.8.4。在我自己的使用过程中,总有一些不爽。因为我下载的那个包里默认的主题样式是下图这样的,使用起来很难和具体的网页风格去配合。 一开始,我准备去动手&am…...
做评选活动的网站/淘宝关键词排名优化技巧
mysql登录密码忘记,其实解决办法很简单,只需要在mysql的主配置文件my.cnf里添加一行“跳过授权表”的参数选择即可!在my.cnf中添加下面一行:[roottest-huanqiu ~]# vim /etc/my.cnf //在[mysqld]区域里添加........s…...
网站建设的重要性意义与价值/今日头条极速版最新
linux中的线程分为用户线程和内核线程,用户线程是标准的线程,完全的自主性,完全的抢占性;但是内核线程就不那么好了,某种意义上没有用户线程那么清闲,这个怎么理解呢?用户线程的编写者只需要实现…...
深圳市建委网站/企业网站推广的形式有
链接: 1、 RAM、ROM、内存还有硬盘,它们到底有什么区别 2、ROM 一、ROM的定义 ROM :只读内存(Read-Only Memory)简称) ROM是只读存储器(Read-Only Memory)的简称,是一种只能读出事先所存数…...