算法第四版 Algorithms Part 1动态联通性

news2024/11/23 19:32:44

联通性检测用途

  • 照片中的像素
  • 网络中的计算机
  • 社交网络中的朋友
  • 计算机芯片中的电路元器件
  • 数学集合中的元素
  • Fortan程序中的变量
  • 复合体系中的金属位
    在这里插入图片描述

假定已连接等价于

  • 反身的: p与p本身是连接的.
  • 对称的: 如果p连接到q,那么q也链接到p
  • 传递的: 如果p连接到q并且q连接到r,那么p连接到r.

在这里插入图片描述

连接的组成

在这里插入图片描述

Union-find数据类型(API)

在这里插入图片描述
目标:为union-find设计有效的数据结构

  • 对象N的数量可能是巨大的
  • 操作次数M可能是巨大的
  • 查找操作和union链接操作可能是混合在一起的
type UF struct
func (uf UF)NewUF(N int) 使用N个对象(0-N-1)初始化union-find数据结构
func union(p, q int) 在p和q之间添加连接
func connected(p, q int) 判断p和q是否相连

动态连接客户端

  • 从标准输入stdin中读取输入
  • 重复:
    1.从标准输入获取整数对
    2.如果他们不相连, 连接他们并打印这一对数字
package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"

	"github.com/iqer/algo4_go/algs4"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()

	n, _ := strconv.Atoi(scanner.Text())
	uf := algs4.NewUF(n)
	for scanner.Scan() {
		line := scanner.Text()
		values := strings.Split(line, " ")
		p, _ := strconv.Atoi(values[0])
		q, _ := strconv.Atoi(values[1])
		uf.Union(p, q)
	}
}

quick-find 一种贪心算法

在这里插入图片描述
不同的点只有当在数组中的项是一样的时候, 那么他们是连通的.
校验p和q是否有相同的id
在这里插入图片描述

quick-find的实现在这里插入图片描述

func NewUF(n int) *UF {
	uf := UF{n: n}
	uf.id = make([]int, n)
	// 将读取到的数字存在于一个数组中
	// 每个索引就代表着一个数
	// 索引对应的值就是连通的点的索引值
	// 之后如果不同索引位置上的值相同, 就代表这些索引位置代表的点是连通的
	for i := 0; i < n; i++ {
		uf.id[i] = i
	}
	return &uf
}

func (uf *UF) connected(p, q int) bool {
	return uf.id[p] == uf.id[q]
}

func (uf *UF) Union(p, q int) {
	pid := uf.id[p]
	qid := uf.id[q]
	for i := 0; i < len(uf.id); i++ {
		if uf.id[i] == pid {
			uf.id[i] = qid
		}
	}
}

分析算法效率

算法初始化union操作find查找操作
快速查找O(N)O(N)1

尝试一种快速合并的算法

一种’懒的方法’, 尽量避免计算直到不得不进行计算
在这里插入图片描述
依然使用数组, 不过将其看作一组树即一片森林的表示.
Find查找操作就变成寻找两者是否拥有同样的parent节点, 如果有就是相连的.
这样做调整时, 只需要将p的根节点指向q的根节点, 就可以了.

func (uf *UF) root(i int) int {
	for i != uf.id[i] {
		i = uf.id[i]
	}
	return i
}

func (uf *UF) connected(p, q int) bool {
	return uf.id[p] == uf.id[q]
}

func (uf *UF) Union(p, q int)  {
	i := uf.root(p)
	j := uf.root(q)
	uf.id[i] = j
}

分析对比一下 quick-union还是太慢了

算法初始化union操作find查找操作
quick-findO(N)O(N)1
quick-uniono(N)O(N)O(N)

quick-find劣势

  • Union操作代价高昂(N维路径)
  • 树时平的, 但维持他们保持平的代价很高

quick-union劣势

  • 树变高了
  • 查找操作复杂度很高(可能是N维操作)

对quick-union的改进

改进方式1: 权重

在这里插入图片描述
避免将更大的树放在低位
在这里插入图片描述
上图对比普通的quick-union操作和带权重的union操作, 可以看到带权重的操作对树高有所控制.

package algs4

type UF struct {
	id   []int
	n    int
	size map[int]int
}

func NewUF(n int) *UF {
	uf := UF{n: n}
	uf.id = make([]int, n)
	uf.size = map[int]int{}
	// 将读取到的数字存在于一个数组中
	// 每个索引就代表着一个数
	// 索引对应的值就是连通的点的索引值
	// 之后如果不同索引位置上的值相同, 就代表这些索引位置代表的点是连通的
	for i := 0; i < n; i++ {
		uf.id[i] = i
		uf.size[i] = 1
	}
	return &uf
}

func (uf *UF) root(i int) int {
	for i != uf.id[i] {
		i = uf.id[i]
	}
	return i
}

func (uf *UF) connected(p, q int) bool {
	return uf.root(p) == uf.root(q)
}

// improved quick-union

func (uf *UF) Union(p, q int) {
	i := uf.root(p)
	j := uf.root(q)
	if i == j {
		return
	}
	if uf.size[i] < uf.size[j] {
		uf.id[i] = j
		uf.size[j] += uf.size[i]
	} else {
		uf.id[j] = i
		uf.size[i] += uf.size[j]
	}
}

在这里插入图片描述
树高在logN

分析带权重的quick-union

算法初始化union操作find查找操作
quick-findO(N)O(N)1
quick-uniono(N)O(N)O(N)
带权重的QUNlogNlogN

继续的改进方式2: path compression路径压缩

func (uf *UF) root(i int) int {
	for i != uf.id[i] {
		// 路径压缩, 使得每一个节点挂到它的祖父辈节点下
		uf.id[i] = uf.id[uf.id[i]]
		i = uf.id[i]
	}
	return i
}

算法性能对比

算法最差情况耗时
quick-findMN
quick-unionMN
weighted QUN+MlogN
QU+path compressionN+MlogN
weighted QU + path compressionN+MlogN

Union-Find的应用场景

在这里插入图片描述

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

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

相关文章

港科夜闻|香港科大近百名创新企业家回归母校庆祝大学首个「独角兽日」

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大近百名创新企业家回归母校庆祝大学首个「独角兽日」。这些香港科大毕业的创业者&#xff0c;参与创立了五间独角兽企业或上市公司&#xff0c;以及近90间初创企业&#xff0c;包括现正快速崛起、有潜力成为下一间…

【Linux】守护进程(附终端、进程组、会话的介绍)

目录 1、终端2、进程组3、会话4、守护进程 橙色 1、终端 echo $$ 可以查看当前终端进程的id 默认情况下(没有重定向)&#xff0c;每个进程的标准输入、标准输出和标准错误输出都指向控制终端、进程从标准输入读也就是读用户的键盘输入&#xff0c;进程往标准输出或标准错误…

PGXC GaussDB

PGXCA PGXC&#xff08;PostgreSQL eXtended Coordinator&#xff09;是一个基于 PostgreSQL 架构的分布式数据库解决方案。它扩展了 PostgreSQL&#xff0c;为用户提供了在多个节点上分布式存储和处理数据的能力。 PGXC 的设计目标是将 PostgreSQL 扩展为能够处理大规模数据…

2023 年互联网上 10个最佳联盟营销论坛(付费和免费)

2023 年互联网上 10个最佳联盟营销论坛&#xff08;付费和免费&#xff09; 在文章中&#xff0c;我将分享 2023 年的 10 个最佳联盟营销论坛。 您是联盟营销的新手并正在寻找向专业人士学习的地方吗&#xff1f; 您来对地方了&#xff0c;我们赞赏您加入联盟营销论坛的决定…

【C++初阶】9. string类的模拟实现

string类的完整实现放这里啦&#xff01;快来看看吧 1. string类的成员 string类的作用就是将字符串类型实现更多功能&#xff0c;运算符重载&#xff0c;增删改查等等操作&#xff0c;所以其成员就包含char*的字符串 private:char* _str;size_t _capacity;size_t _size;2. …

三对角矩阵原理及C++实现

一、三对角矩阵 1.三对角矩阵概念 2.三对角矩阵元素数量 对于给定n阶方阵M&#xff0c;若其为三对角矩阵&#xff0c;则元素个数N为&#xff1a; 若n1&#xff0c;此时方阵只有一个元素M[0][0]&#xff0c;由定义知该元素也在三对角线上。故N1。若n>1&#xff0c;由三对角…

chatgpt赋能python:Python文件夹的使用和优化

Python 文件夹的使用和优化 文件夹是计算机操作系统中最基本的存储单位之一。在计算机领域&#xff0c;文件夹也被称为目录。文件夹中可以存储多个文件或其他文件夹&#xff0c;使得文件在计算机中可以更好的组织和管理。基于Python语言&#xff0c;我们可以很容易地创建、读取…

javaEE基于springboot的小区社区文化活动报名系统jsp生活服务网站

社区文化宣传网站采用的开发框架为springboot框架&#xff0c;开发工具采用Eclipse&#xff0c;idea 服务器用的是Tomcat。编码语言是Java&#xff0c;数据库采用Mysql数据库。 本社区文化宣传网站&#xff0c;主要服务的用户是社区附近的居民&#xff0c;为居民展示最新的新闻…

带电更换10kV架空线路直线杆绝缘子(绝缘手套作业法)

一、现场复勘 1.核对线路及杆塔号 线路双重名称及杆号无误。 2.检查杆身质量 3.检查电杆埋深 4.检查拉线受力情况 5.检查相邻杆情况 作业点及相邻侧电杆之间导线应无断股等现象。 6.检查气象条件 作业前需进行湿度和风速的测量&#xff0c;风力大于5级&#xff0c;或湿度大…

5分钟搞定验证码

验证码生成 本效果是利用easy-captcha工具包实现&#xff0c;首先需要添加相关依赖到pom.xml中&#xff0c;代码如下&#xff1a; <dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6…

链式二叉树高质量OJ—【Leedcode】

目录 ​编辑 1. 单值二叉树 题目 题目分析 代码实现 不带返回值版本 带返回值版本 递归展开图 2. 相同的树 题目 题目分析 代码实现 3. 对称二叉树 题目 题目分析 代码实现 4. 另外一颗子树 题目 题目分析 代码实现 递归展开图 5. 二叉树的前、中、后序遍…

给电脑重装系统有什么坏处吗

电脑重装系统是解决一些问题的常见方法&#xff0c;但是它也存在一些潜在的坏处。本文将为您详细介绍电脑重装系统的坏处&#xff0c;并提供一些注意事项&#xff0c;帮助您做出明智的决策。 工具/原料&#xff1a; 系统版本&#xff1a;Windows10 品牌型号&#xff1a;惠普…

涂鸦智能发布全球首款Matter+Alexa Built-in涂鸦智选智慧中控屏L

根据Parks Associates今年4月发布的《Next-Generation Smart Home: Building for the Future》显示&#xff0c;41%的美国互联网家庭拥有智能家居设备&#xff0c;越来越多的家庭正在部署全屋智能。 当家中出现越来越多的智能设备时&#xff0c;智慧中控屏&#xff0c;凭借“所…

行业报告 | AIGC应用与实践展望报告:人工智能重塑内容产业的作业模式

原创 | 文 BFT机器人 前言 Introduction 不可否认AIGC的出现似乎已经让大家预见了Al应用的拐点&#xff0c;其创造性与智能性一夜之间刷新了大众认知。但去伪存真&#xff0c;在市场火爆的背后其真正的应用及商业价值几何&#xff0c;更待我们冷静地剖析。 01 概念重生&#…

破解excel单元格保护

EI目录.xlsx 被保护&#xff0c;想查其中期刊&#xff0c;却不能直接复制。 step1.文件后缀改成.rarstep2.360压缩包打开&#xff0c;找到【sheet1.xml】step3.使用记事本打开&#xff0c;删除部分指定代码step4.后缀改回.xlsx 我是用360压缩包可以直接在.rar中 进行修改。 …

生态环境监测好帮手——便携式水污染物监测设备

便携式水污染物监测设备也可以称作便携式水质多参数检测仪 根据生态环境保护需要而专门研发的一款可快速准确测定地表水、地下水、城市污水及工业废水中CODcr、氨氮、总磷、总氮等50余种指标&#xff0c;浓度直读&#xff1b;可广泛用于水厂、食品、化工、冶金、环保及制药行业…

《机器人SLAM导航核心技术与实战》第1季:第5章_机器人主机

视频讲解 【第1季】5.第5章_机器人主机-视频讲解 【第1季】5.1.第5章_机器人主机_X86与ARM主机对比-视频讲解 【第1季】5.2.第5章_机器人主机_ARM主机树莓派3B-视频讲解 【第1季】5.3.第5章_机器人主机_ARM主机RK3399-视频讲解 【第1季】5.4.第5章_机器人主机_ARM主机Jetso…

chatgpt赋能python:Python文件大小函数:了解文件大小的方法和掌握文件操作技巧

Python文件大小函数&#xff1a;了解文件大小的方法和掌握文件操作技巧 文件大小是我们经常需要考虑的一个问题&#xff0c;无论是在计算机存储、文件上传、程序优化等场景中都需要关注。在Python中&#xff0c;我们可以通过文件操作函数来查询文件大小&#xff0c;这篇文章将…

看了两位阿里P10的成长经历,我的认知升华了

两位 P10 大佬的成长经历 相信不少人和我一样&#xff0c;对这些高段位大佬的成长经历有很强的好奇心&#xff0c;想知道他们是如何达到这一步的&#xff0c;这期间有什么关键的选择。这一节我们来看下他们的成长经历&#xff0c;通过了解前辈是如何成长的&#xff0c;可以帮助…

Oracle11G安装说明

Oracle11G安装说明 一、序二、安装安装依赖包基础环境配置安装Oracle 三、配置Oracle 一、序 Oracle和MySQL语法区别&#xff1a;https://blog.csdn.net/lanmuhhh2015/article/details/97763615 Oracle创建用户、角色、授权、建表&#xff1a;https://www.cnblogs.com/roger1…