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

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

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

92850

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

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

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

    Golang垃圾回收 屏障技术

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

    2.4K30

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

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

    20450

    文心一言 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 算法的正确性,即调整后的堆仍然满足最大堆性质。 在这里插入图片描述 总结 在这里插入图片描述

    15320

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

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

    9910

    【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仍然保持最大堆的性质

    37310

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

    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代码执行适当的操作来维持该循环不变式。

    82350

    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 不变,适合尺寸固定的堆。 由于先弹出后添加,因此返回的值可能大于添加的项目。

    78210

    讨厌算法的程序员 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代码执行适当的操作来维持该循环不变式。

    78750

    Go 运行时面试题

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

    38610

    Golang垃圾回收机制

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

    25810

    文心一言 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: 将元素插入堆中,并检查插入后的堆是否满足最小堆的性质。如果不满足,则对堆进行调整,直到满足最小堆的性质为止。

    18850

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

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

    1.1K40

    数据小白必看:七大排序算法超详细讲解(上)

    稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,在排完序列后,r[i]仍在r[j]之前...例如: 第1个3是在第二个3之前,排序后,两个位置发生前后变化,这种是不稳定性。如果前后排序没有发生变化那么是稳定性。...在起始i的时候,执行j循环的时候,确实j+1下标,但是在每次指向完一次j的循环,j的下标就向前移动,而在j移动的过程中i是不变的。...在比较过程中,可以算是每次从该位置,从后开始比较,如果两个位置前后大小交换,那么在交换的元素的前后位置可能也要发生交换。...1改成gap吗?

    15210

    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] 来加速 还有什么好玩的吗?

    47330

    【初阶数据结构与算法】排序算法总结篇(每个小节后面有源码)(直接插入、希尔、选择、堆、冒泡、快速、归并、计数以及非递归快速、归并排序)

    一、直接插入排序 稳定性分析 (1)稳定性指的是在排序过程中,两个相等的元素在排序后的相对位置不会发生变化,直接插入排序是稳定的排序算法 (2)在排序过程中,它通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描...由于相等元素在插入时不会改变它们在已排序序列中的相对位置(即如果两个相等元素在原序列中相邻,它们在排序后的序列中仍然相邻),因此直接插入排序是稳定的 时间复杂度: (1)最优情况:O(n)(当输入序列已经是有序的情况下...,由于分组和增量递减的特性,相同大小的元素可能会因为分组后的插入排序操作而发生相对位置的改变。...因此,堆排序不能保证相同元素的相对位置在排序前后保持不变 时间复杂度: (1)最优情况:O(n log n)(无论输入序列如何,堆排序都需要构建堆和调整堆,这两个过程的时间复杂度都是O(n log...因此,非递归快速排序也不能保证排序前后相等元素的相对位置保持不变。

    7310

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

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

    11910

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

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

    95720
    领券