Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tree 如何证明堆数据结构中的子级位于:2*n和2*n+;1._Tree_Binary Tree_Heap - Fatal编程技术网

Tree 如何证明堆数据结构中的子级位于:2*n和2*n+;1.

Tree 如何证明堆数据结构中的子级位于:2*n和2*n+;1.,tree,binary-tree,heap,Tree,Binary Tree,Heap,这不是家庭作业问题,我今天学习了堆数据结构,我不知道如何证明这个关系是正确的。谢谢。通过归纳法证明: 根的子级(1)->child1=2*1=2,child2=2*1+1=3true 假设第k个元素的子元素是->child1=2k,child2=2k+1 证明第(k+1)个元素的子元素是child1=2*(k+1),child2=2(k+1)+1(证明这一点) 证据3: 因为第k个元素的子元素是2k和2k+1(基于假设),所以后面的两个元素是2k+2和2k+3 2k+2=2(k+1)(证明了k+

这不是家庭作业问题,我今天学习了堆数据结构,我不知道如何证明这个关系是正确的。谢谢。

通过归纳法证明:

  • 根的子级(1)->child1=2*1=2,child2=2*1+1=3true
  • 假设第k个元素的子元素是->child1=2k,child2=2k+1
  • 证明第(k+1)个元素的子元素是child1=2*(k+1),child2=2(k+1)+1(证明这一点)
  • 证据3: 因为第k个元素的子元素是2k和2k+1(基于假设),所以后面的两个元素是2k+2和2k+3

    2k+2=2(k+1)(证明了k+1的第一个孩子)(a)

    2k+3=2k+2+1=2(k+1)+1(证明了k+1的第二个孩子)(b)


    从(a)和(b)->因此3是有效的,因此元素n的子元素是2n和2n+1

    这里是一个没有归纳的证明,从我的观点来看,它更直观和有洞察力。 这里有4个心理步骤向我证明了这种关系

    把树压平。 让我们按以下方式枚举树的所有顶点:

    以下是这些verices在阵列中的外观:

    在数组中分离同级。 我们可以注意到,每两个连续节点(第一个节点除外)都是某个公共顶点的子节点:
    1[2 3[4 5][
    6 7][8 9]

    以不同的方式构建此阵列。 现在让我们按相反的顺序思考。如果我们有一个成对的数组:[(2,3),(4,5),(6,7),(8,9)],我们想将它们聚合到一个数组中,会怎么样

    假设我们已经放置了前3对:
    [23][45][[67]

    最终数组中数字8的索引是什么? 我们知道我们已经放置了3对,它们在开始时占据了3*2=6的位置,所以我们将占据第7位

    如果我们对成对的位置进行编码,它将如下所示:

    pair<int, int> pairs[4] = { {2, 3}, {4, 5}, {6, 7}, {8, 9} };
    int aggregate[2 * 4];
    for (int i = 0; i < 4; i++)
    {
        aggregate[2 * i] = pairs[i].first;
        aggregate[2 * i + 1] = pairs[i].second;
    }
    
    pairpairs[4]={{2,3},{4,5},{6,7},{8,9};
    整数加总[2*4];
    对于(int i=0;i<4;i++)
    {
    聚合[2*i]=对[i]。第一;
    聚合[2*i+1]=对[i]。第二;
    }
    
    关键部分是数组聚合的索引[2*i]。在这段代码中,很明显可以看出为什么我们要乘以2——我们这样做,因为我们必须跳过前面的i-1

    结合树的展平和对的聚集
    现在我们需要看到构建聚合对数组和二叉树展平之间的对应关系。每对兄弟姐妹都有父母。如果两个兄弟姐妹(2,3)和(4,5)在数组中相邻,则它们的父母也相邻。兄弟姐妹(2,3)有父母1,兄弟姐妹(4,5)有父母2,兄弟姐妹(6,7)有父母3。因此,父对象就像这个成对数组中的一个索引
    对[4]={(2,3)、(4,5)、(6,7)、(8,9)}
    ,当我们使用2*i访问它的左子对象时,我们可以考虑跳过前面顶点生成的子对象对。

    你知道没有归纳法的证明吗?归纳证明对我来说一般意义不大。三年前我就知道堆是如何工作的,今天我试图推断这些事实,但这并不容易。我把这归咎于我是通过归纳证明学来的。归纳证明不会产生任何直觉,不会产生心理图像,也不会与我已经知道的任何东西产生共鸣。@Pixar归纳证明非常简单,一旦你理解了它,就很容易描绘和应用。信不信由你,但基本的证明程序并不多。据我所知,这里有四种解释:当然,归纳法证明简单易行,但它不能让你记住东西,因为它是基于猜测(猜测优先法=))。例如,你可以很容易地用归纳法证明1+..+n=n*(n+1)/2,但我从来没有这样教过孩子这个公式。它没有给你任何直觉,完全没有良心。只有在我别无选择的情况下,我才会坚持归纳法。@Pixar-hmm归纳法不是靠猜测来证明的。它以推理规则为核心。证明使用了我们理解的最简单的基础。如果你理解归纳法,那么你就会意识到它是多么深刻。你不能因为不理解它就说它没有任何直觉(我理解归纳法,我没有说归纳法是用guess=)证明的,这不是一个结果,它或多或少是堆的定义。