倍增技术也叫指针跳跃技术,因为涉及到指针,所以特别适合处理链表或有向有根树之类的数据结构,在图论和涉及链表的算法中有广泛的应用。

每当循环调用倍增技术时,要处理的数据之间的距离就会逐步加倍,经过k次迭代就可以完成2k数据的计算。

下面以最经典的表序问题和求森林的根问题来说明此技术。

1表序问题

问题描述

给定一个包含 n 个元素的链表,每个元素 i 到 i 所指元素的距离用数组 d [ i ] 表示,每个元素指向的下一个元素用数组 p [ i ] 表示,初始化链表从表头指向表尾,规定表尾元素指向自己,距离为 0,d [ n ] = 0;p [ n ] = n。求每个元素 i 到表尾的距离。

如下图,n=8,距离数组d = [6,10,12,4,8,1,4,0],所指元素数组p = [2,3,4,5,6,7,8,8]。具体地,d [ 1 ] = 6表示元素 1 到所指元素的距离是 6,p [ 1 ] = 2表示元素 1 指向的下一个元素是 2。求所有元素到表尾元素 8 的距离。

思想描述

顾名思义,指针跳跃技术,每个元素不需要一步一步计算到表尾的距离,可以根据指针的指示跳过某些元素,直接跨好几步。当所指元素数组 p 全部更新为8时,表示所有元素都直接指向了表尾元素,且指针权值就是各元素到表尾元素的距离。

初始化
d=[6,10,12,4,8,1,4,0]p=[2,3,4,5,6,7,8,8]\begin{aligned} &d=[6,10,12,4,8,1,4,0]\\ &p=[2,3,4,5,6,7,8,8] \end{aligned} ​d=[6,10,12,4,8,1,4,0]p=[2,3,4,5,6,7,8,8]​
步骤1:每一个元素 i 都顺着指针的指示 指向步骤1中元素 i 的下一个元素所指的元素,如因为元素1在步骤1中指向元素2,元素2在步骤1中指向元素3,所以元素1的下一个元素更新为3,距离更新为元素1到元素2的距离+元素2到元素3的距离,对每个元素重复该操作,得到更新后的数组:
d=[16,22,16,12,9,5,4,0]p=[3,4,5,6,7,8,8,8]\begin{aligned} &d=[16,22,16,12,9,5,4,0]\\ &p=[3,4,5,6,7,8,8,8] \end{aligned} ​d=[16,22,16,12,9,5,4,0]p=[3,4,5,6,7,8,8,8]​
更新后的直观图:

步骤2:每一个元素 i 都顺着指针的指示 指向步骤2中元素 i 的下一个元素所指的元素,如因为元素1在步骤2中指向元素3,元素3在步骤2中指向元素5,所以元素1可以直接跳过元素4指向元素5,距离更新为元素1到元素3的距离+元素3到元素5的距离,对每个元素重复该操作,得到更新后的数组:
d=[32,32,25,17,13,5,4,0]p=[5,6,7,8,8,8,8,8]\begin{aligned} &d=[32,32,25,17,13,5,4,0]\\ &p=[5,6,7,8,8,8,8,8] \end{aligned} ​d=[32,32,25,17,13,5,4,0]p=[5,6,7,8,8,8,8,8]​
更新后的直观图:

步骤3:每一个元素 i 都顺着指针的指示 指向步骤3中元素 i 的下一个元素所指的元素,如因为元素1在步骤3中指向元素5,元素5在步骤3中指向元素8,所以元素1可以直接跳过元素67指向元素8,距离更新为元素1到元素5的距离+元素5到元素8的距离,对每个元素重复该操作,得到更新后的数组:
d=[45,37,29,17,13,5,4,0]p=[8,8,8,8,8,8,8,8]\begin{aligned} &d=[45,37,29,17,13,5,4,0]\\ &p=[8,8,8,8,8,8,8,8] \end{aligned} ​d=[45,37,29,17,13,5,4,0]p=[8,8,8,8,8,8,8,8]​
更新后的直观图:

至此,所有的元素都直接指向了表尾元素,指针的权值d就是元素到表尾元素的距离,算法结束。

伪代码

初始化d,p
while(数组p中存在非表尾元素的值)for all 元素i 并行do:if (p[i] != p[p[i]])d[i] = d[i] + d[p[i]]p[i] = p[p[i]]end ifend for
end while
输出d

时间复杂度分析

整个算法只递归了3次就算出了规模为8的表序问题,如果不加倍增技术,时间复杂度需要 O( n ),加了倍增技术的时间复杂度只需要 O( log2n )。

在遗传算法中,走n步可以搜索到2n的搜索空间,就是因为使用了倍增技术。
如果将每一步骤的操作用n个处理器同时并行计算这n个数据的更新,在主处理器串行计算各步骤,计算效率会大大减小,同时计算开销也会由于处理器的增多而增加。

2求森林的根问题

问题描述

给定由一组有根有向树构成的森林F,F包含n个结点,每个结点 i 从下向上指向自己的父结点 j,用 p [ i ] = j 表示,如果 i 是根节点,规定 p [ i ] = i ;求森林的根。

如下图,n=13,初始化数组p = [5,5,6,6,6,8,8,8,10,11,12,13,13]。具体地,p [ 1 ] = 5表示结点 1 的父结点是 5。求森林的根结点。

思想描述

解决该问题的思想与表序问题基本一致,流程如下:

步骤1

p更新为
p=[6,6,8,8,8,8,8,8,11,12,13,13,13]p = [6,6,8,8,8,8,8,8,11,12,13,13,13]p=[6,6,8,8,8,8,8,8,11,12,13,13,13]
步骤2

p更新为
p=[8,8,8,8,8,8,8,8,13,13,13,13,13]p = [8,8,8,8,8,8,8,8,13,13,13,13,13]p=[8,8,8,8,8,8,8,8,13,13,13,13,13]
至此,对于所有结点 i ,都有 p [ i ] = p [ p [ i ] ] ,算法结束,该森林的根为8和13。

倍增设计技术(指针跳跃技术)——表序问题——求森林的根相关推荐

  1. 饮水思源--浅析深度学习框架设计中的关键技术

    点击上方"深度学习大讲堂"可订阅哦! 编者按:如果把深度学习比作一座城,框架则是这座城中的水路系统,而基于拓扑图的计算恰似城中水的流动,这种流动赋予了这座城以生命.一个优雅的框架在 ...

  2. 用户界面设计的技巧与技术 (作者Scott W.Ambler)

    对大多数人来说,用户界面就是软件本身.所以,掌握用户界面设计的技巧与技术是让软件走向市场的最直观因素.原文来源于http://WWW.ambysoft.com/userInterfaceDesign. ...

  3. 领域驱动设计,盒马技术团队这么做

    阿里妹导读:好的设计模式.代码架构可以大大降低产品的故障率,提高产品的质量.大家都使用的熟悉的设计模式未必是最好的设计模式,引入新的思想,并借鉴应用到自己的设计中,是正道. 今天,我们邀请盒马资深技术 ...

  4. LoRa技术实现水表抄表远距离无线传输方案的应用

    LoRa是LPWAN通信技术中的一种,是美国Semtech公司采用和推广的一种基于扩频技术的超远距离无线传输方案.这一方案改变了以往关于传输距离与功耗的折衷考虑方式,为用户提供一种简单的能实现远距离. ...

  5. 大四课程设计之基于RFID技术的考勤管理系统(三)数据库设计

    ---------------------------------------------------------------------------------------- 源码下载地址: htt ...

  6. 如何利用计算机实现非线性转换,基于cass数控绕线机非线性算法的设计与实现-计算机应用技术专业论文.docx...

    基于cass数控绕线机非线性算法的设计与实现-计算机应用技术专业论文 J J Dissertation Dissertation Submitted to Hangzhou D i anz i Uni ...

  7. 辽宁师范大学海华学院计算机科学与技术,辽宁师范大学海华学院计算机科学与技术专业综合评价简况表.doc...

    辽宁师范大学海华学院计算机科学与技术专业综合评价简况表.doc 辽宁省普通高等学校本科专业综合评价 简况表 单位代码及名称: 13215辽宁师范大学海华学院 专业代码及名称: 080605计算机科学与 ...

  8. 响应式网页设计_响应式网页设计中的常用技术

    响应式网页设计 在先前的文章中,我讨论了为什么Web准备就绪以进行响应式设计 ,以及网站所有者如何使用用户设备和屏幕空间的上下文来跨各种尺寸的屏幕(包括PC,电话) 为用户提供上下文相关的体验.和控制 ...

  9. 产品设计学习过程中的技术和方法

    在产品设计的过程中,当你心中有创意设计时,你需要写下这个创意设计,并生成一个例子标记,以便总结你以前的想法.此时,你需要设计性能.在设计性能的过程中,我们需要使用各种设计工具,这些设计工具的应用技术和 ...

  10. Windows中多指针输入技术的实现与应用(4多鼠标输入的底层实现)

    Windows中多指针输入技术的实现与应用(4多鼠标输入的底层实现) 湖南大学 谢祁衡 2 多鼠标输入的底层实现 2.1 通过开发过滤式鼠标驱动的实现 此技术最先由M.Westergaard在[9]中 ...

最新文章

  1. python subprocess_python subprocess
  2. 敏捷个人2012.8月份线下活动报道:Toastmasters、团队管理
  3. 【Android NDK 开发】JNI 引用 ( 全局引用 | NewGlobalRef | DeleteGlobalRef )
  4. CTFshow 命令执行 web29
  5. BAPI:KBPP_EXTERN_UPDATE_CO, TCODE:CJ30/CJ40
  6. 算法题目——多米诺骨牌问题(POJ-2663)
  7. 计算机会考补考时间安排,2019-2020学年第二学期初补考考试安排(实时更新)
  8. java录制pcm文件_AudioRecord录制PCM格式的语音示例
  9. JS精粹知识点和我的解释
  10. 微信僵尸粉源码php,清除微信僵尸粉工具源码
  11. android随机抽奖代码_随机抽奖生成器app下载|随机抽奖生成器软件下载_v1.0_9ht安卓下载...
  12. iframe 防止挂马的问题
  13. NTL库在Win上基于MinGW的安装
  14. 认识一下身边的互联网---经典互联网书籍阅读总结
  15. 国外EDU教育邮箱功能简介
  16. hex颜色透明度对比表
  17. 关于近年来走红的某类综艺节目
  18. 在以太坊开发自己的ERC-20代币及如何ICO
  19. 怎样按照STAR法则制作简历
  20. 想学ui设计从哪里入手?基础怎么入门学习UI设计呢?

热门文章

  1. 怎样装系统(附图文教程)
  2. FreeWheel创始人/CTO于晶纯访谈:具备大局观方能洞若观火
  3. Ruoyi 整合Flowable UI Modeler 6.7.2
  4. 利用树莓派组建支持迅雷离线下载的NAS
  5. 订单可视化(智能制造、流程再造、企业信息化) 第三篇 订单可视化定义及目标
  6. 计算机系要高考英语口语吗,高考英语口语考试_高考英语口语考试到底有什么用?很重要么?...
  7. 04、Flutter FFI 字符串
  8. 恶意软件隐身术:把可执行文件隐藏在注册表里
  9. Poco库使用:文件压缩和解压缩
  10. 在unity3D中添加字体