首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

讨厌算法的程序员 2 | 证明算法的正确性

第1篇介绍了插入排序算法,这里要提出一个问题:学习算法仅仅是积累一个又一个的算法实现? 当然不是。比算法本身更重要也更基础的,是对算法的分析:能够证明其正确性,能够理解其效率。...这里定义循环不变的窍门就是:结合导致循环终止的条件一起定义循环不变。 03 证明插入排序的正确性 利用上一节的“循环不变”,我们证明第1篇中介绍的插入排序的正确性。...对于插入排序,一开始我们就注意到其玩扑克牌中的应用,这里面有一个关键的认知:我们手中已经摸到的牌始终是排好序的,也就是我们找到的循环不变:A[1 ‥ j-1]循环的三个阶段均为有序。...无论循环前,循环中,还是循环,它都是不变的。...从上图中(a)中,有序数组中只有5一个元素; 2、保持:其次处理第二条性质:证明每次迭代保持循环不变循环的每次迭代过程中,A[1 ‥ j-1]的“有序性”仍然保持

86450

讨厌算法的程序员 2 - 证明算法的正确性

第1篇介绍了插入排序算法,这里要提出一个问题:学习算法仅仅是积累一个又一个的算法实现? 当然不是。比算法本身更重要也更基础的,是对算法的分析:能够证明其正确性,能够理解其效率。...这里定义循环不变的窍门就是:结合导致循环终止的条件一起定义循环不变。 证明插入排序的正确性 利用上一节的“循环不变”,我们证明第1篇中介绍的插入排序的正确性。...对于插入排序,一开始我们就注意到其玩扑克牌中的应用,这里面有一个关键的认知:我们手中已经摸到的牌始终是排好序的,也就是我们找到的循环不变:A[1 ‥ j-1]循环的三个阶段均为有序。...无论循环前,循环中,还是循环,它都是不变的。...从上图中(a)中,有序数组中只有5一个元素; 保持:其次处理第二条性质:证明每次迭代保持循环不变循环的每次迭代过程中,A[1 ‥ j-1]的“有序性”仍然保持

1.4K50
您找到你想要的搜索结果了吗?
是的
没有找到

Golang垃圾回收 屏障技术

标记-清扫算法 标记-清扫算法是一种追踪的垃圾回收算法,并不会在对象死亡立即将其清除掉,而是一定条件下触发,统一校验系统中的存活对象,进行回收工作。...强三色不变中,黑色赋值器只存在到黑色对象或灰色对象的指针,因为此时所有黑色对象到白色对象的引用都是被禁止的。弱三色不变中,黑色赋值器允许存在到白色对象的指针,但这个白色对象是被保护的。...插入屏障 插入屏障拦截将白色指针插入黑色对象的操作,标记其对应对象为灰色状态,这样就不存在黑色对象引用白色对象的情况了,满足强三色不变,如上图例中,插入指针f时将C对象标记为灰色。...对栈上指针的写入添加写屏障的成本很高,所以Go选择仅对堆上的指针插入增加写屏障,这样就会出现在扫描结束,栈上仍存在引用白色对象的情况,这时的栈是灰色的,不满足三色不变,所以需要对栈进行重新扫描使其变黑...由于结合了Yuasa的删除写屏障和Dijkstra的插入写屏障的优点,只需要在开始时并发扫描各个goroutine的栈,使其变黑并一直保持,这个过程不需要STW,而标记结束,因为栈扫描始终是黑色的

2.3K30

文心一言 VS 讯飞星火 VS chatgpt (58)-- 算法导论6.4 2题

通过保持这个循环不变量,我们可以确保每次迭代顶元素(A[i])是未排序部分中的最大元素,而子数组 A[i+1..n] 是已排序的部分。...因此,每次迭代,未排序部分中的最小元素会被交换到已排序的部分中,从而逐步完成排序过程。 使用这个循环不变量可以帮助我们理解和追踪算法的状态,并且证明算法的正确性时提供了一个有用的工具。...在这里插入图片描述 讯飞星火: 使用HEAPSORT算法时,确实需要使用循环不变量来保证算法的正确性。...因此,使用这个循环不变量可以保证 HEAPSORT 的正确性。 在这里插入图片描述 chatglm: 使用上述循环不变量时,HEAPSORT 的正确性可以得到保证。...最后一次迭代结束,整个数组就被排序完毕,满足子数组A[1..n]包含了数组A[1..n]中的所有元素,并以升序排列。 在这里插入图片描述 总结 在这里插入图片描述

18650

文心一言 VS 讯飞星火 VS chatgpt (66)-- 算法导论6.5 5题

这样可以维护的性质,并在后续的插入、删除等操作中保持正确性。 因此,使用HEAP-INCREASE-KEY时,确保子数组A[1..A.heap-size]满足最大堆的性质是正确的。...在这里插入图片描述 chatglm: 使用 HEAP-INCREASE-KEY 函数时,需要保证的最大性质,否则可能会导致的不稳定。...,如果 A[1] 本来就不在顶,那么调整的结果可能会破坏的最大性质。...HEAP-INCREASE-KEY 的目标是将某个节点的值增加,并使得调整仍然满足最大堆的性质。 通过 HEAP-INCREASE-KEY 算法的实现,我们可以确保调整仍然满足最大堆性质。...综上所述,使用这个循环不变量可以确保 HEAP-INCREASE-KEY 算法的正确性,即调整仍然满足最大堆性质。 在这里插入图片描述 总结 在这里插入图片描述

13120

写对代码的利器——“循环不变性”

初学者构建复杂代码时,往往会吃不准——我这样写对?本文就从”不变性“(invariants)的角度,给大家一些增加信心的”打开方式“。 循环不变性 如果大家看过算法导论,应该对这个词不陌生。...粗略来说,算法中,循环不变性(loop invariants)指的是迭代三个关键环节(初始化、迭代中、结束时)上维持某种性质的不变。...插入:每次将边界处的元素插入到有序集中合适的位置,保持其仍然有序。 结束时:可得,有序集扩张到了整个数组,即我们排好序了。...通过迭代的三个环节中保持有序集的一直有序,我们可以很有信心:我们最后得到的数组一定是有序的。聪明的你可能已经感觉到了,这不就是数学归纳法?...数据 众所周知,并发编程、分布编程都很难写对。但如果我们能保证数据的“不变性”(当然,这里有点偷换概念了,英文中其实是 immutable)。就可以放心的对同一份数据进行反复读取、多次实验。

6710

【42期】盘点那些必问的数据结构算法题之二叉

即一个包含n个元素的二叉高度为 lgn 。 2 保持的性质 本文主要建立一个最大堆,最小堆原理类似。...为了保持的性质,maxHeapify(int A[], int i) 函数让数组 A 最大堆中下降,使得以 i 为根的子树成为最大堆。...for (i = n/2-1; i >= 0; i--) { maxHeapify(A, i, n); } } 之所以这个函数是正确的,我们需要来证明一下,可以使用循环不变来证明...循环不变for循环开始前,结点 i+1、i+2…N-1 都是一个最大堆的根。...保持:因为结点 i 的子结点标号都比 i 大,根据循环不变的定义,这些子结点都是最大堆的根,所以调用 maxHeapify() ,i 成为了最大堆的根,而 i+1, i+2, …, N-1仍然保持最大堆的性质

35410

讨厌算法的程序员 | 第五章 合并算法

2、为了避免每次执行基本步骤都要检查是否有为空,每个的底部放置一张“哨兵”牌(哨兵通常包含一个特殊值,用于简化代码),值为∞。它可以保证直到两牌都露出∞时,其他牌都已经放置到输出。...、保持、和终止阶段循环不变都成立,从而可以通过终止时的不变推断出算法是正确的。...代码中的12~17行是唯一的循环,循环不变是什么呢?...A[p ‥ k-1]为空; 保持:即要证明某次迭代之前不变为真,下次迭代之前不变仍为真; 假设某次迭代前,L[i] ≤ R[j],此时L[i]是未被复制回数组A的最小元素; 与此同时,数组A[p ‥...增加k的值(for循环)和i的值(第15行代码),即为下次迭代前重新建立了该循环不变; 反之,若L[i] > R[j],则第16~17代码执行适当的操作来维持该循环不变

77550

讨厌算法的程序员 5 - 合并算法

为了避免每次执行基本步骤都要检查是否有为空,每个的底部放置一张“哨兵”牌(哨兵通常包含一个特殊值,用于简化代码),值为∞。它可以保证直到两牌都露出∞时,其他牌都已经放置到输出。...、保持、和终止阶段循环不变都成立,从而可以通过终止时的不变推断出算法是正确的。...代码中的12~17行是唯一的循环,循环不变是什么呢?...A[p ‥ k-1]为空; 保持:即要证明某次迭代之前不变为真,下次迭代之前不变仍为真; 假设某次迭代前,L[i] ≤ R[j],此时L[i]是未被复制回数组A的最小元素; 与此同时,数组A[p...增加k的值(for循环)和i的值(第15行代码),即为下次迭代前重新建立了该循环不变; 反之,若L[i] > R[j],则第16~17代码执行适当的操作来维持该循环不变

76350

Python

此种数据结构适用于经常变化、更新的序列中,需要时刻维护最小 / 最大值的情况 插入新元素或 pop 顶元素重新维护结构的时间复杂度为 O(logn) Python 内置 heapq 官方文档:...使用方法 创建 heapq.heapify(x) 已经存在的列表基础上创建的,需要先创建列表 x,采用 heapq.heapify(x) 将列表转化为 import heapq a = [9,3,5...heapq.heapify(a) print(a) --> [1, 2, 5, 2, 9, 13, 7, 8, 3, 24] 添加元素 heapq.heappush(heap, item) 将值项推送到堆上,保持不变...弹出元素 heapq.heappop(heap) 从中弹出并返回最小的项目,保持不变。如果为空,则会引发 IndexError。 要访问最小的项目而不弹出它,请使用 heap[0]。...该操作比两个单独操作效率高(实现上先弹出元素添加元素),过程中size 不变,适合尺寸固定的。 由于先弹出添加,因此返回的值可能大于添加的项目。

74810

Go 运行时面试题

goroutine 执行写操作时,比如更新对象字段或者切片内容,可能会破坏垃圾收集器对已经到达的颜色不变性(三色标记法中的不变性)。写屏障确保了修改对象引用时,相关联的对象不会被错误地回收。...插入写屏障主要作用是提供对三色标记中不变性的维护,其工作原理如下: 对象变黑前阶段: 当垃圾回收器标记内的对象时,所有新写入的指针(指从一个对象指向另一个对象的引用)都要经过写屏障。... Go 中,写屏障偏向于插入的行为,它在并发垃圾回收期间维护不变性,保证被程序修改的引用不会引起不可达的活动对象被错误收集。 15....混合写屏障结合了插入和删除写屏障的特点,但它更偏向于插入行为。其基本思路是在对象引用发生变更时进行干预,以帮助垃圾回收器正确识别存活的对象。...通过插入的行为,它避免了对象图并行标记期间被错误地更新,导致一些应该存活的对象被错误地识别为垃圾。同时,由于它并不处理所有类型的写操作,它比一个全面的删除插入写屏障对性能的影响要小。

24510

Golang垃圾回收机制

屏障机制 程序的执行过程中添加一个屏障机制实现两种不变性 屏障机制分为插入屏障和删除屏障,插入屏障实现的是强三色不变,删除屏障则实现了弱三色不变。...为了保证栈的运行效率,屏障只对堆上的内存对象启用,栈上的内存会在GC结束启用STW重新扫描。 插入屏障 使程序满足强三色不变性,当白色节点被黑色节点引用时,将白色节点变为灰色,从而保留这个节点。...缺陷:如果白色节点被栈上的黑色节点引用,不会触发插入屏障,最后还是会被删除。 删除屏障 使程序满足弱三色不变性,当白色节点的引用被删除时,将白色节点变为灰色,从而保留这个节点。...Go1.8混合写屏障 概念 解决插入写屏障和删除写屏障结束时需要STW来重新扫描栈带来的性能问题 步骤 GC开始将栈上的对象全部扫描并标记为黑色 GC期间任何在栈新创建的对象都标记为黑色 堆上被删除的对象标记为灰色...堆上被添加的对象标记为灰色 操作场景 某时刻栈和的情况(栈一开始就都是黑的) 栈上新增对象4,堆上新增对象d 栈上删除对象1,堆上删除对象3 栈上删除栈上新增,堆上删除堆上新增

20510

文心一言 VS 讯飞星火 VS chatgpt (64)-- 算法导论6.5 3题

其中,min_heap_insert 插入元素到最小堆中,min_heap_extract_min 提取最小元素并保持最小堆性质,min_heap_decrease_key 修改元素值并保持最小堆性质,...在这里插入图片描述 chatglm: 以下是使用最小堆实现最小优先队列的伪代码: HEAP-MINIMUM(heap, n): // 最小堆中找到最小的元素 // heap 是...在这里插入图片描述 在这里插入图片描述 通义千问: 下面是最小堆常用操作的伪代码: HEAP-MINIMUM: 对顶元素进行比较,如果比底元素小,则将底元素替换为顶元素;否则,保持顶元素不变...HEAP-DECREASE-KEY: 对顶元素的键值进行比较,如果比底元素的键值小,则将底元素替换为顶元素;否则,保持顶元素不变。...MIN-HEAP-INSERT: 将元素插入中,并检查插入是否满足最小堆的性质。如果不满足,则对进行调整,直到满足最小堆的性质为止。

16650

揭秘Go语言GC(垃圾回收)的技术演进

屏障机制 GC进行垃圾回收的时候,满足下面两种情况之一时,即可保对象不丢失。这两种方式就是「强三色不变」和「弱三色不变」。...强三色不变 不允许黑色对象直接指向白色对象,这样就不会有白色对象被误删的情况 弱三色不变 所有被黑色对象引用的白色对象都处于灰色保护状态。...弱三色不变强调,黑色对象可以引用白色对象,但是白色对象上游必须有灰色对象来保证其安全被扫描到 基于上面两种方式,golang的GC算法演化出了两种屏障方式,他们就是「插入屏障」和「删除屏障」 插入屏障...栈空间的特点是容量小,但是要求相应速度快,因为函数调用弹出频繁使用, 所以“插入屏障”机制,「栈空间的对象操作中不使用. 而仅仅使用在空间对象的操作中」....为了更好的理解,我们来看这样的一个过程 程序根节点是分为栈空间和空间的,只有空间的对象启用插入屏障机制 因为并发等各种原因,此时对象4需要指向对象8,对象1需要指向对象9 因为对象4空间,启用了插入屏障

66840

oeasy教您玩转vim - 15 - # 行内查找

还是继续 motion 里面 ^ 、$ 之后找 还是左右移动这里面发现有个 f 看起来是查找某个字符的样子 查找字符 看起来就像 f谁就跳到谁那里 我们来试一下 先下载个素材 #下载素材 git...试试 反向继续查找 中指向下找到 , 确实可以让他反向 搜索范围还是被限制了本行 帮助里面还提到的 F 是干什么用的?...反向跳跃 F 和 f 一样 都是行内跳跃 但是 F 是反向跳跃 反向跳跃练习 这个时候如果 ; 就是继续反向查找 保持跳跃的方向不变 只要是方向不变就是 ; 保持小拇指的感觉 方向改变的话 就是 ,...,并切换到插入模式 2 f o 找到第 2 个 o ; 保持查找方向不变 继续向前 , 反向查找o 2 ; 保持查找方向不变 向前移动到第 2 个 o 2 , 反向查找 第 2 个 o 总结...跳跃 向前跳跃是 f 向后跳跃是 F 继续 保持方向是 ; 改变方向是 , 可以加上 [count] 来加速 还有什么好玩的

44130

使用嵌入SQL(五)

例如,某些成功的嵌入SQL操作未设置%ROWID。执行这些操作,%ROWID是未定义的或保持设置为其先前值。...%ROWID由下面描述的嵌入SQL操作设置。如果该操作不成功或成功完成,但未获取或修改任何行,则%ROWID值与其先前值保持不变:未定义,或由先前的嵌入SQL操作设置为某个值。...经过多行操作之后,%ROWID变量包含系统分配的最后一条插入,更新或删除的记录的RowID(对象ID)的值。如果未插入,更新或删除任何记录,则%ROWID变量值将保持不变。...%ROWID值与其先前的值(如果有)保持不变。如果基于游标的SELECT仅返回聚合函数值,则不会设置%ROWID。...完成简单的SELECT语句,%ROWID值将保持不变Dynamic SQL中,相应的%ROWID属性返回插入,更新或删除的最后一条记录的RowID值。

2.6K20

生成人工智能对产品战略意味着什么以及如何评估它

回顾过去的 10 年,我们可以看到一最初受到巨大炒作但最终没有成为“主流”的技术。无论是因为未能跨越鸿沟而最终被抛弃,还是采用率滞后的情况下勉强存在,你可能很清楚我在说什么。...虽然将生成人工智能放在这些被过度吹捧的技术中似乎很容易,不管是因为你认为它很烦人、分散注意力,甚至让人焦虑,但这样做是愚蠢的。 潘多拉的盒子已经打开。...我们的基础技术不断变化,而用户及其问题的基本原则保持不变。 创新来自发现用户自己认为重要的用户问题,然后以更快,更便宜和更轻松的方式解决这些问题。...汽车比马车更好地解决了从 A 到 B 的核心问题,但问题本身保持不变。 这对生成 AI 意味着需要转变可以和/或应该解决的问题范例。...但这有意义?构建这样的功能肯定需要相当的时间和精力投入,但发布可能会发生什么?我们的赌注是:寂静。 用户阅读个人博客的主要目的是为了获取特定的技术答案?可能不是。

8010

GO语言学习笔记 | 垃圾回收机制剖析

标记阶段, 从根对象开始进行图遍历(深度优先/广度优先),将可达对象设置标记(用黑色标记)。 标记阶段完成,对象H仍然为白色,未被标记。...内存屏障指令前的内存操作一定会在内存屏障指令的操作之前执行。 内存屏障技术本身并不能用来保证三色不变性。...} 我们看下插入写屏障如何保证强三色不变性: 先假设栈对象也开启了写屏障 仍然以前面的例子来说明: 当插入C->D这条边时,触发插入写屏障。...只goroutine维度STW无法保证第二种场景垃圾回收能正确回收。 (四)混合写屏障 插入写屏障和删除写屏障针对栈对象不开启写屏障的限制条件都有了解决方案,都能够满足三色不变性。...第一种场景是同一个goroutine进行的, 第二种场景,因为是将栈对象下游移动到黑色的对象下游,如果我们对对象开启插入写屏障,就可以保证对象不被错误回收。

30010

详解gc(垃圾回收)机制(一)

” 和 “弱三色不变”。...强三色不变 不允许黑色对象引用白色对象 弱三色不变 所有被黑色对象引用的白色对象都处于灰色保护状态。...为了遵循这2种规则,继而产生了2种 "屏障机制",也就是 "插入屏障"和"删除屏障" 插入屏障   A 对象引用 B 对象的时候,B 对象被标记为灰色。...(将 B 挂在 A 下游,B 必须被标记为灰色) 由于栈空间容量小,响应速度快,函数调用弹出频繁,所以插入屏障栈对象操作中不使用,仅在对象中使用 所以回收完对象时,栈空间对象需要进行一次 停止程序运行...,重新标记 黑白,再进行回收栈对象 删除屏障 GC开始,所有需要删除的 白色/灰色 对象都标记为灰色 通过插入屏障和删除屏障,解决了上面的引用删除问题 但是,删除屏障的回收精度低,只要是GC开始

78520

常见的数据结构及应用

其表现形式如下图栈的特点栈的特点是先进出(FILO):第一个入栈的元素最后一个被访问或被取出,或者说最后一个入栈的元素会第一个被访问或被取出。栈只允许栈顶进行插入和删除操作。...AVL树AVL树是一种自平衡的二叉查找树,进行插入和删除操作时,会通过左旋或者右旋自动调整自身的结构,确保每个节点的左右子树的高度差不超过1,从而保持树的平衡,也保障了查询的时间复杂度为O(log n...以下图为例,当插入节点5时,节点7左右子树的高度差为2,这时候节点7就需要进行右旋保持树的平衡。右旋就是:以某个节点为旋转点,其左子节点变为其父节点,左子节点的右子节点变为其左子节点,右子节点不变。...虽然AVL通过旋转保持树的平衡,但是插入和删除频繁的场景中,频繁的旋转会导致性能下降,为解决此问题红黑树被提出。红黑树红黑树大家应该都比较耳熟,但是理不理解是另一回事,面试的时候应该经常会被问到。...下图左为最大堆的表示,右不符合为一个完全二叉树(依次从左到右插入的节点为完全二叉树)。通常被用作优先队列,因为的根节点总是最大的或最小的。

20951
领券