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

news/2024/12/29 11:45:21/

联通性检测用途

  • 照片中的像素
  • 网络中的计算机
  • 社交网络中的朋友
  • 计算机芯片中的电路元器件
  • 数学集合中的元素
  • 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 mainimport ("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 algs4type UF struct {id   []intn    intsize 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] = iuf.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-unionfunc (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] = juf.size[j] += uf.size[i]} else {uf.id[j] = iuf.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.ppmy.cn/news/93607.html

相关文章

【C++11】C++11新增语法特性 右值引用/移动语义/完美转发

C11 右值引用 1 右值引用1.1 左值 、 右值1.2 左值引用 VS 右值引用1.3 谈谈C11引入右值引用的意义1.4 左值引用和右值引用的一些细节问题 2 移动语义3 完美转发4 总结 1 右值引用 1.1 左值 、 右值 在C中所有的值不是左值就是右值。左值是指表达式结束后依然存在的持久化对象…

太稳了,支付系统就该这么设计

支付中心系统对内为各个业务线提供统一的支付、退款等服务&#xff0c;对外对接三方支付或银行服务实现资金的流转。如下图&#xff1a; 大部分公司基本都是这样的架构&#xff0c;主要有以下几方面的优点&#xff1a; 形成统一支付服务&#xff0c;降低业务线接入成本及重复研…

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

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

MySQL基础(三十七)主从复制

1. 主从复制概述 1.1 如何提升数据库并发能力 此外&#xff0c;一般应用对数据库而言都是“ 读多写少 ”&#xff0c;也就说对数据库读取数据的压力比较大&#xff0c;有一个思路就是采用数据库集群的方案&#xff0c;做 主从架构 、进行 读写分离 &#xff0c;这样同样可以提…

ChatGPT被广泛应用,潜在的法律风险有哪些?

ChatGPT由OpenAI开发&#xff0c;2022年11月一经面世便引发热烈讨论&#xff0c;用户数持续暴涨。2023年初&#xff0c;微软成功将ChatGPT接入其搜索引擎Bing中&#xff0c;市场影响力迅速提升&#xff0c;几乎同一时间&#xff0c;谷歌宣布其研发的一款类似人工智能应用Bard上…

[数据结构] AVL树的插入旋转 和 概念理解

文章目录 定义 && 性质定义性质 实现思路架构节点AVL树框架Insert&#xff08;插入&#xff09;左单旋右单旋左右双旋右左双旋 定义 && 性质 定义 二叉搜索树虽可以缩短查找的效率&#xff0c;但 如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c…

【运维知识进阶篇】Ansible自动化运维-Ansible安装与主机列表

很开心大家可以看到这篇文章&#xff0c;Ansible是一个自动化统一配置管理工具&#xff0c;集成了丰富模块以及功能组件&#xff0c;可以通过一个命令对多台服务器主机实现批量化操作&#xff0c;减少重复性工作和维护成本&#xff0c;提高工作效率。 同类软件有很多&#xff…

记录--前端小票打印、网页打印

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 一、小票打印 目前市面上的小票打印机大多采用的打印指令集为ESC/POS指令&#xff0c;它可以使用ASCII码、十进制、十六进制来控制打印&#xff0c;我们可以使用它来控制字体大小、打印排版、字体加粗…